diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index dcf0a60cb2182509b15252cee216513834e3c6a2..2858ef0c977c36f80b81e79abbb9a08fd46313fc 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -84,7 +84,7 @@
 		},
 		{
 			"ImportPath": "github.com/robertkrimen/otto",
-			"Rev": "c21072f61b64b51ea58138ccacf0a85d54b9f07c"
+			"Rev": "53221230c215611a90762720c9042ac782ef74ee"
 		},
 		{
 			"ImportPath": "github.com/syndtr/goleveldb/leveldb",
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/ast/comments.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/ast/comments.go
new file mode 100644
index 0000000000000000000000000000000000000000..227e34ecbef79c9f010d1c6a748e910b9e317c54
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/ast/comments.go
@@ -0,0 +1,92 @@
+package ast
+
+import (
+	"fmt"
+	"github.com/robertkrimen/otto/file"
+)
+
+// CommentPosition determines where the comment is in a given context
+type CommentPosition int
+
+const (
+	_        CommentPosition = iota
+	LEADING                  // Before the pertinent expression
+	TRAILING                 // After the pertinent expression
+	KEY                      // After a key or keyword
+	COLON                    // After a colon in a field declaration
+	FINAL                    // Final comments in a block, not belonging to a specific expression or the comment after a trailing , in an array or object literal
+	TBD
+)
+
+// Comment contains the data of the comment
+type Comment struct {
+	Begin    file.Idx
+	Text     string
+	Position CommentPosition
+}
+
+// String returns a stringified version of the position
+func (cp CommentPosition) String() string {
+	switch cp {
+	case LEADING:
+		return "Leading"
+	case TRAILING:
+		return "Trailing"
+	case KEY:
+		return "Key"
+	case COLON:
+		return "Colon"
+	case FINAL:
+		return "Final"
+	default:
+		return "???"
+	}
+}
+
+// String returns a stringified version of the comment
+func (c Comment) String() string {
+	return fmt.Sprintf("Comment: %v", c.Text)
+}
+
+// CommentMap is the data structure where all found comments are stored
+type CommentMap map[Node][]*Comment
+
+// AddComment adds a single comment to the map
+func (cm CommentMap) AddComment(node Node, comment *Comment) {
+	list := cm[node]
+	list = append(list, comment)
+
+	cm[node] = list
+}
+
+// AddComments adds a slice of comments, given a node and an updated position
+func (cm CommentMap) AddComments(node Node, comments []*Comment, position CommentPosition) {
+	for _, comment := range comments {
+		comment.Position = position
+		cm.AddComment(node, comment)
+	}
+}
+
+// Size returns the size of the map
+func (cm CommentMap) Size() int {
+	size := 0
+	for _, comments := range cm {
+		size += len(comments)
+	}
+
+	return size
+}
+
+// MoveComments moves comments with a given position from a node to another
+func (cm CommentMap) MoveComments(from, to Node, position CommentPosition) {
+	for i, c := range cm[from] {
+		if c.Position == position {
+			cm.AddComment(to, c)
+
+			// Remove the comment from the "from" slice
+			cm[from][i] = cm[from][len(cm[from])-1]
+			cm[from][len(cm[from])-1] = nil
+			cm[from] = cm[from][:len(cm[from])-1]
+		}
+	}
+}
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/ast/node.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/ast/node.go
index eb46f8601996b2b6d237e4d3c670b0a79976c1f1..8a651dc2f133a8298fde221c24f76bdd77de2355 100644
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/ast/node.go
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/ast/node.go
@@ -86,6 +86,11 @@ type (
 		Identifier Identifier
 	}
 
+	EmptyExpression struct {
+		Begin file.Idx
+		End   file.Idx
+	}
+
 	FunctionLiteral struct {
 		Function      file.Idx
 		Name          *Identifier
@@ -185,6 +190,7 @@ func (*BracketExpression) _expressionNode()     {}
 func (*CallExpression) _expressionNode()        {}
 func (*ConditionalExpression) _expressionNode() {}
 func (*DotExpression) _expressionNode()         {}
+func (*EmptyExpression) _expressionNode()       {}
 func (*FunctionLiteral) _expressionNode()       {}
 func (*Identifier) _expressionNode()            {}
 func (*NewExpression) _expressionNode()         {}
@@ -399,6 +405,7 @@ func (self *BracketExpression) Idx0() file.Idx     { return self.Left.Idx0() }
 func (self *CallExpression) Idx0() file.Idx        { return self.Callee.Idx0() }
 func (self *ConditionalExpression) Idx0() file.Idx { return self.Test.Idx0() }
 func (self *DotExpression) Idx0() file.Idx         { return self.Left.Idx0() }
+func (self *EmptyExpression) Idx0() file.Idx       { return self.Begin }
 func (self *FunctionLiteral) Idx0() file.Idx       { return self.Function }
 func (self *Identifier) Idx0() file.Idx            { return self.Idx }
 func (self *NewExpression) Idx0() file.Idx         { return self.New }
@@ -447,6 +454,7 @@ func (self *BracketExpression) Idx1() file.Idx     { return self.RightBracket +
 func (self *CallExpression) Idx1() file.Idx        { return self.RightParenthesis + 1 }
 func (self *ConditionalExpression) Idx1() file.Idx { return self.Test.Idx1() }
 func (self *DotExpression) Idx1() file.Idx         { return self.Identifier.Idx1() }
+func (self *EmptyExpression) Idx1() file.Idx       { return self.End }
 func (self *FunctionLiteral) Idx1() file.Idx       { return self.Body.Idx1() }
 func (self *Identifier) Idx1() file.Idx            { return file.Idx(int(self.Idx) + len(self.Name)) }
 func (self *NewExpression) Idx1() file.Idx         { return self.RightParenthesis + 1 }
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/builtin_math.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/builtin_math.go
index a9f4a55c1a1591025bf7117f6ff55bebf089d8f0..7ce90c339efb2e4954bedd5ad3c2d5c7f744f136 100644
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/builtin_math.go
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/builtin_math.go
@@ -117,7 +117,13 @@ func builtinMath_pow(call FunctionCall) Value {
 }
 
 func builtinMath_random(call FunctionCall) Value {
-	return toValue_float64(rand.Float64())
+	var v float64
+	if call.runtime.random != nil {
+		v = call.runtime.random()
+	} else {
+		v = rand.Float64()
+	}
+	return toValue_float64(v)
 }
 
 func builtinMath_round(call FunctionCall) Value {
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/cmpl_parse.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/cmpl_parse.go
index e758a52301b00edba792d8be0c8dcde37b364092..f1e002d39030eaf55bbd0deeca5710cc992a4bc8 100644
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/cmpl_parse.go
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/cmpl_parse.go
@@ -82,6 +82,9 @@ func (cmpl *_compiler) parseExpression(in ast.Expression) _nodeExpression {
 			identifier: in.Identifier.Name,
 		}
 
+	case *ast.EmptyExpression:
+		return nil
+
 	case *ast.FunctionLiteral:
 		name := ""
 		if in.Name != nil {
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/otto.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/otto.go
index 2ec033cbc80a16438c2a42be97b4f6fbb2560815..6135330828397b8bf8d18c334d2b837bd16ba337 100644
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/otto.go
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/otto.go
@@ -363,6 +363,10 @@ func (self Otto) SetDebuggerHandler(fn func(vm *Otto)) {
 	self.runtime.debugger = fn
 }
 
+func (self Otto) SetRandomSource(fn func() float64) {
+	self.runtime.random = fn
+}
+
 // Context is a structure that contains information about the current execution
 // context.
 type Context struct {
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/expression.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/expression.go
index 8baf22f7cf2fe82f95cb1a2fe11b4209b996454e..a23a7279a42d9510aabe880bae4480de99476857 100644
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/expression.go
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/expression.go
@@ -12,10 +12,14 @@ func (self *_parser) parseIdentifier() *ast.Identifier {
 	literal := self.literal
 	idx := self.idx
 	self.next()
-	return &ast.Identifier{
+	comments := self.findComments(false)
+	exp := &ast.Identifier{
 		Name: literal,
 		Idx:  idx,
 	}
+
+	self.commentMap.AddComments(exp, comments, ast.TRAILING)
+	return exp
 }
 
 func (self *_parser) parsePrimaryExpression() ast.Expression {
@@ -196,11 +200,20 @@ func (self *_parser) parseVariableDeclarationList(var_ file.Idx) []ast.Expressio
 	var list []ast.Expression
 
 	for {
-		list = append(list, self.parseVariableDeclaration(&declarationList))
+		comments := self.findComments(false)
+
+		decl := self.parseVariableDeclaration(&declarationList)
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(decl, comments, ast.LEADING)
+			self.commentMap.AddComments(decl, self.findComments(false), ast.TRAILING)
+		}
+
+		list = append(list, decl)
 		if self.token != token.COMMA {
 			break
 		}
 		self.next()
+
 	}
 
 	self.scope.declare(&ast.VariableDeclaration{
@@ -211,10 +224,13 @@ func (self *_parser) parseVariableDeclarationList(var_ file.Idx) []ast.Expressio
 	return list
 }
 
-func (self *_parser) parseObjectPropertyKey() (string, string) {
+func (self *_parser) parseObjectPropertyKey() (string, string, []*ast.Comment) {
 	idx, tkn, literal := self.idx, self.token, self.literal
 	value := ""
 	self.next()
+
+	comments := self.findComments(false)
+
 	switch tkn {
 	case token.IDENTIFIER:
 		value = literal
@@ -238,15 +254,14 @@ func (self *_parser) parseObjectPropertyKey() (string, string) {
 			value = literal
 		}
 	}
-	return literal, value
+	return literal, value, comments
 }
 
 func (self *_parser) parseObjectProperty() ast.Property {
-
-	literal, value := self.parseObjectPropertyKey()
+	literal, value, comments := self.parseObjectPropertyKey()
 	if literal == "get" && self.token != token.COLON {
 		idx := self.idx
-		_, value := self.parseObjectPropertyKey()
+		_, value, _ := self.parseObjectPropertyKey()
 		parameterList := self.parseFunctionParameterList()
 
 		node := &ast.FunctionLiteral{
@@ -261,7 +276,7 @@ func (self *_parser) parseObjectProperty() ast.Property {
 		}
 	} else if literal == "set" && self.token != token.COLON {
 		idx := self.idx
-		_, value := self.parseObjectPropertyKey()
+		_, value, _ := self.parseObjectPropertyKey()
 		parameterList := self.parseFunctionParameterList()
 
 		node := &ast.FunctionLiteral{
@@ -277,63 +292,128 @@ func (self *_parser) parseObjectProperty() ast.Property {
 	}
 
 	self.expect(token.COLON)
+	comments2 := self.findComments(false)
 
-	return ast.Property{
+	exp := ast.Property{
 		Key:   value,
 		Kind:  "value",
 		Value: self.parseAssignmentExpression(),
 	}
+
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(exp.Value, comments, ast.KEY)
+		self.commentMap.AddComments(exp.Value, comments2, ast.COLON)
+	}
+	return exp
 }
 
 func (self *_parser) parseObjectLiteral() ast.Expression {
 	var value []ast.Property
 	idx0 := self.expect(token.LEFT_BRACE)
+
+	var comments2 []*ast.Comment
 	for self.token != token.RIGHT_BRACE && self.token != token.EOF {
+
+		// Leading comments for object literal
+		comments := self.findComments(false)
 		property := self.parseObjectProperty()
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(property.Value, comments, ast.LEADING)
+			self.commentMap.AddComments(property.Value, comments2, ast.LEADING)
+		}
 		value = append(value, property)
 		if self.token == token.COMMA {
 			self.next()
+
+			// Find leading comments after trailing comma
+			comments2 = self.findComments(false)
 			continue
 		}
 	}
 	idx1 := self.expect(token.RIGHT_BRACE)
 
-	return &ast.ObjectLiteral{
+	exp := &ast.ObjectLiteral{
 		LeftBrace:  idx0,
 		RightBrace: idx1,
 		Value:      value,
 	}
+
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(exp, comments2, ast.FINAL)
+	}
+	self.consumeComments(exp, ast.FINAL)
+
+	return exp
 }
 
 func (self *_parser) parseArrayLiteral() ast.Expression {
-
 	idx0 := self.expect(token.LEFT_BRACKET)
+	var comments2 []*ast.Comment
+	var comments []*ast.Comment
 	var value []ast.Expression
 	for self.token != token.RIGHT_BRACKET && self.token != token.EOF {
+		// Find leading comments for both empty and non-empty expressions
+		comments = self.findComments(false)
+
 		if self.token == token.COMMA {
 			self.next()
-			value = append(value, nil)
+
+			// This kind of comment requires a special empty expression node.
+			empty := &ast.EmptyExpression{self.idx, self.idx}
+
+			if self.mode&StoreComments != 0 {
+				self.commentMap.AddComments(empty, comments, ast.LEADING)
+				self.commentMap.AddComments(empty, comments2, ast.LEADING)
+			}
+
+			value = append(value, empty)
+
+			// This comment belongs to the following expression, or trailing
+			comments2 = self.findComments(false)
+
 			continue
 		}
-		value = append(value, self.parseAssignmentExpression())
+
+		exp := self.parseAssignmentExpression()
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(exp, comments, ast.LEADING)
+			self.commentMap.AddComments(exp, comments2, ast.LEADING)
+		}
+
+		value = append(value, exp)
 		if self.token != token.RIGHT_BRACKET {
 			self.expect(token.COMMA)
 		}
+
+		// This comment belongs to the following expression, or trailing
+		comments2 = self.findComments(false)
 	}
 	idx1 := self.expect(token.RIGHT_BRACKET)
 
-	return &ast.ArrayLiteral{
+	array := &ast.ArrayLiteral{
 		LeftBracket:  idx0,
 		RightBracket: idx1,
 		Value:        value,
 	}
+
+	// This is where comments after a possible trailing comma are added
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(array, comments2, ast.FINAL)
+	}
+
+	return array
 }
 
 func (self *_parser) parseArgumentList() (argumentList []ast.Expression, idx0, idx1 file.Idx) {
 	idx0 = self.expect(token.LEFT_PARENTHESIS)
 	if self.token != token.RIGHT_PARENTHESIS {
 		for {
-			argumentList = append(argumentList, self.parseAssignmentExpression())
+			comments := self.findComments(false)
+			exp := self.parseAssignmentExpression()
+			if self.mode&StoreComments != 0 {
+				self.commentMap.AddComments(exp, comments, ast.LEADING)
+			}
+			argumentList = append(argumentList, exp)
 			if self.token != token.COMMA {
 				break
 			}
@@ -346,12 +426,17 @@ func (self *_parser) parseArgumentList() (argumentList []ast.Expression, idx0, i
 
 func (self *_parser) parseCallExpression(left ast.Expression) ast.Expression {
 	argumentList, idx0, idx1 := self.parseArgumentList()
-	return &ast.CallExpression{
+	exp := &ast.CallExpression{
 		Callee:           left,
 		LeftParenthesis:  idx0,
 		ArgumentList:     argumentList,
 		RightParenthesis: idx1,
 	}
+
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(exp, self.findComments(false), ast.TRAILING)
+	}
+	return exp
 }
 
 func (self *_parser) parseDotMember(left ast.Expression) ast.Expression {
@@ -402,6 +487,11 @@ func (self *_parser) parseNewExpression() ast.Expression {
 		node.LeftParenthesis = idx0
 		node.RightParenthesis = idx1
 	}
+
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node, self.findComments(false), ast.TRAILING)
+	}
+
 	return node
 }
 
@@ -414,6 +504,10 @@ func (self *_parser) parseLeftHandSideExpression() ast.Expression {
 		left = self.parsePrimaryExpression()
 	}
 
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(left, self.findComments(false), ast.TRAILING)
+	}
+
 	for {
 		if self.token == token.PERIOD {
 			left = self.parseDotMember(left)
@@ -442,6 +536,10 @@ func (self *_parser) parseLeftHandSideExpressionAllowCall() ast.Expression {
 		left = self.parsePrimaryExpression()
 	}
 
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(left, self.findComments(false), ast.TRAILING)
+	}
+
 	for {
 		if self.token == token.PERIOD {
 			left = self.parseDotMember(left)
@@ -476,12 +574,18 @@ func (self *_parser) parsePostfixExpression() ast.Expression {
 			self.nextStatement()
 			return &ast.BadExpression{From: idx, To: self.idx}
 		}
-		return &ast.UnaryExpression{
+		exp := &ast.UnaryExpression{
 			Operator: tkn,
 			Idx:      idx,
 			Operand:  operand,
 			Postfix:  true,
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(exp, self.findComments(false), ast.TRAILING)
+		}
+
+		return exp
 	}
 
 	return operand
@@ -496,16 +600,30 @@ func (self *_parser) parseUnaryExpression() ast.Expression {
 		tkn := self.token
 		idx := self.idx
 		self.next()
-		return &ast.UnaryExpression{
+
+		comments := self.findComments(false)
+
+		exp := &ast.UnaryExpression{
 			Operator: tkn,
 			Idx:      idx,
 			Operand:  self.parseUnaryExpression(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(exp.Operand, comments, ast.LEADING)
+		}
+		return exp
 	case token.INCREMENT, token.DECREMENT:
 		tkn := self.token
 		idx := self.idx
 		self.next()
+
+		comments := self.findComments(false)
+
 		operand := self.parseUnaryExpression()
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(operand, comments, ast.LEADING)
+		}
 		switch operand.(type) {
 		case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
 		default:
@@ -531,11 +649,18 @@ func (self *_parser) parseMultiplicativeExpression() ast.Expression {
 		self.token == token.REMAINDER {
 		tkn := self.token
 		self.next()
+
+		comments := self.findComments(false)
+
 		left = &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    next(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left.(*ast.BinaryExpression).Right, comments, ast.LEADING)
+		}
 	}
 
 	return left
@@ -548,11 +673,18 @@ func (self *_parser) parseAdditiveExpression() ast.Expression {
 	for self.token == token.PLUS || self.token == token.MINUS {
 		tkn := self.token
 		self.next()
+
+		comments := self.findComments(false)
+
 		left = &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    next(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left.(*ast.BinaryExpression).Right, comments, ast.LEADING)
+		}
 	}
 
 	return left
@@ -566,11 +698,18 @@ func (self *_parser) parseShiftExpression() ast.Expression {
 		self.token == token.UNSIGNED_SHIFT_RIGHT {
 		tkn := self.token
 		self.next()
+
+		comments := self.findComments(false)
+
 		left = &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    next(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left.(*ast.BinaryExpression).Right, comments, ast.LEADING)
+		}
 	}
 
 	return left
@@ -590,31 +729,55 @@ func (self *_parser) parseRelationalExpression() ast.Expression {
 	case token.LESS, token.LESS_OR_EQUAL, token.GREATER, token.GREATER_OR_EQUAL:
 		tkn := self.token
 		self.next()
-		return &ast.BinaryExpression{
+
+		comments := self.findComments(false)
+
+		exp := &ast.BinaryExpression{
 			Operator:   tkn,
 			Left:       left,
 			Right:      self.parseRelationalExpression(),
 			Comparison: true,
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(exp.Right, comments, ast.LEADING)
+		}
+		return exp
 	case token.INSTANCEOF:
 		tkn := self.token
 		self.next()
-		return &ast.BinaryExpression{
+
+		comments := self.findComments(false)
+
+		exp := &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    self.parseRelationalExpression(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(exp.Right, comments, ast.LEADING)
+		}
+		return exp
 	case token.IN:
 		if !allowIn {
 			return left
 		}
 		tkn := self.token
 		self.next()
-		return &ast.BinaryExpression{
+
+		comments := self.findComments(false)
+
+		exp := &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    self.parseRelationalExpression(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(exp.Right, comments, ast.LEADING)
+		}
+		return exp
 	}
 
 	return left
@@ -628,12 +791,19 @@ func (self *_parser) parseEqualityExpression() ast.Expression {
 		self.token == token.STRICT_EQUAL || self.token == token.STRICT_NOT_EQUAL {
 		tkn := self.token
 		self.next()
+
+		comments := self.findComments(false)
+
 		left = &ast.BinaryExpression{
 			Operator:   tkn,
 			Left:       left,
 			Right:      next(),
 			Comparison: true,
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left.(*ast.BinaryExpression).Right, comments, ast.LEADING)
+		}
 	}
 
 	return left
@@ -646,11 +816,18 @@ func (self *_parser) parseBitwiseAndExpression() ast.Expression {
 	for self.token == token.AND {
 		tkn := self.token
 		self.next()
+
+		comments := self.findComments(false)
+
 		left = &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    next(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left.(*ast.BinaryExpression).Right, comments, ast.LEADING)
+		}
 	}
 
 	return left
@@ -663,11 +840,18 @@ func (self *_parser) parseBitwiseExclusiveOrExpression() ast.Expression {
 	for self.token == token.EXCLUSIVE_OR {
 		tkn := self.token
 		self.next()
+
+		comments := self.findComments(false)
+
 		left = &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    next(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left.(*ast.BinaryExpression).Right, comments, ast.LEADING)
+		}
 	}
 
 	return left
@@ -680,11 +864,18 @@ func (self *_parser) parseBitwiseOrExpression() ast.Expression {
 	for self.token == token.OR {
 		tkn := self.token
 		self.next()
+
+		comments := self.findComments(false)
+
 		left = &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    next(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left.(*ast.BinaryExpression).Right, comments, ast.LEADING)
+		}
 	}
 
 	return left
@@ -697,11 +888,18 @@ func (self *_parser) parseLogicalAndExpression() ast.Expression {
 	for self.token == token.LOGICAL_AND {
 		tkn := self.token
 		self.next()
+
+		comments := self.findComments(false)
+
 		left = &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    next(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left.(*ast.BinaryExpression).Right, comments, ast.LEADING)
+		}
 	}
 
 	return left
@@ -714,11 +912,18 @@ func (self *_parser) parseLogicalOrExpression() ast.Expression {
 	for self.token == token.LOGICAL_OR {
 		tkn := self.token
 		self.next()
+
+		comments := self.findComments(false)
+
 		left = &ast.BinaryExpression{
 			Operator: tkn,
 			Left:     left,
 			Right:    next(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left.(*ast.BinaryExpression).Right, comments, ast.LEADING)
+		}
 	}
 
 	return left
@@ -729,13 +934,29 @@ func (self *_parser) parseConditionlExpression() ast.Expression {
 
 	if self.token == token.QUESTION_MARK {
 		self.next()
+
+		// Comments before the consequence
+		comments1 := self.findComments(false)
+
 		consequent := self.parseAssignmentExpression()
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(consequent, comments1, ast.LEADING)
+		}
+
 		self.expect(token.COLON)
-		return &ast.ConditionalExpression{
+
+		// Comments before the alternate
+		comments2 := self.findComments(false)
+		exp := &ast.ConditionalExpression{
 			Test:       left,
 			Consequent: consequent,
 			Alternate:  self.parseAssignmentExpression(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(exp.Alternate, comments2, ast.LEADING)
+		}
+		return exp
 	}
 
 	return left
@@ -783,17 +1004,30 @@ func (self *_parser) parseAssignmentExpression() ast.Expression {
 			self.nextStatement()
 			return &ast.BadExpression{From: idx, To: self.idx}
 		}
-		return &ast.AssignExpression{
+
+		comments := self.findComments(false)
+
+		exp := &ast.AssignExpression{
 			Left:     left,
 			Operator: operator,
 			Right:    self.parseAssignmentExpression(),
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(exp.Right, comments, ast.LEADING)
+		}
+
+		return exp
 	}
 
 	return left
 }
 
 func (self *_parser) parseExpression() ast.Expression {
+
+	comments := self.findComments(false)
+	statementComments := self.fetchComments()
+
 	next := self.parseAssignmentExpression
 	left := next()
 
@@ -811,5 +1045,10 @@ func (self *_parser) parseExpression() ast.Expression {
 		}
 	}
 
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(left, comments, ast.LEADING)
+		self.commentMap.AddComments(left, statementComments, ast.LEADING)
+	}
+
 	return left
 }
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/lexer.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/lexer.go
index bc3e74f77a553eef252dd5c39495f755774f5bb0..a510c76d22ac89247105292982ef2361dd9fe52b 100644
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/lexer.go
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/lexer.go
@@ -120,6 +120,7 @@ func isLineTerminator(chr rune) bool {
 func (self *_parser) scan() (tkn token.Token, literal string, idx file.Idx) {
 
 	self.implicitSemicolon = false
+	self.skippedLineBreak = false
 
 	for {
 		self.skipWhiteSpace()
@@ -238,9 +239,20 @@ func (self *_parser) scan() (tkn token.Token, literal string, idx file.Idx) {
 				tkn = self.switch2(token.MULTIPLY, token.MULTIPLY_ASSIGN)
 			case '/':
 				if self.chr == '/' {
+					if self.mode&StoreComments != 0 {
+						runes := self.readSingleLineComment()
+						literal = string(runes)
+						tkn = token.COMMENT
+						return
+					}
 					self.skipSingleLineComment()
 					continue
 				} else if self.chr == '*' {
+					if self.mode&StoreComments != 0 {
+						literal = string(self.readMultiLineComment())
+						tkn = token.COMMENT
+						return
+					}
 					self.skipMultiLineComment()
 					continue
 				} else {
@@ -411,6 +423,39 @@ func (self *_RegExp_parser) read() {
 	}
 }
 
+func (self *_parser) readSingleLineComment() (result []rune) {
+	for self.chr != -1 {
+		self.read()
+		if isLineTerminator(self.chr) {
+			return
+		}
+		result = append(result, self.chr)
+	}
+
+	// Get rid of the trailing -1
+	result = result[:len(result)-1]
+
+	return
+}
+
+func (self *_parser) readMultiLineComment() (result []rune) {
+	self.read()
+	for self.chr >= 0 {
+		chr := self.chr
+		self.read()
+		if chr == '*' && self.chr == '/' {
+			self.read()
+			return
+		}
+
+		result = append(result, chr)
+	}
+
+	self.errorUnexpected(0, self.chr)
+
+	return
+}
+
 func (self *_parser) skipSingleLineComment() {
 	for self.chr != -1 {
 		self.read()
@@ -442,6 +487,7 @@ func (self *_parser) skipWhiteSpace() {
 			continue
 		case '\r':
 			if self._peek() == '\n' {
+				self.skippedLineBreak = true
 				self.read()
 			}
 			fallthrough
@@ -449,6 +495,7 @@ func (self *_parser) skipWhiteSpace() {
 			if self.insertSemicolon {
 				return
 			}
+			self.skippedLineBreak = true
 			self.read()
 			continue
 		}
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/parser.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/parser.go
index 92ac5b0c70c5f81fb1507d37f2a6caedb5dbdf12..18328edd6c2cd1c9f2603abb574899b9d23a0e8b 100644
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/parser.go
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/parser.go
@@ -49,12 +49,13 @@ type Mode uint
 
 const (
 	IgnoreRegExpErrors Mode = 1 << iota // Ignore RegExp compatibility errors (allow backtracking)
+	StoreComments                       // Store the comments from source to the comments map
 )
 
 type _parser struct {
-	str      string
-	length   int
-	base     int
+	str    string
+	length int
+	base   int
 
 	chr       rune // The current character
 	chrOffset int  // The offset of current character
@@ -79,15 +80,22 @@ type _parser struct {
 	mode Mode
 
 	file *file.File
+
+	comments         []*ast.Comment
+	commentMap       *ast.CommentMap
+	skippedLineBreak bool
 }
 
 func _newParser(filename, src string, base int) *_parser {
 	return &_parser{
-		chr:    ' ', // This is set so we can start scanning by skipping whitespace
-		str:    src,
-		length: len(src),
-		base:   base,
-		file:   file.NewFile(filename, src, base),
+		chr:              ' ', // This is set so we can start scanning by skipping whitespace
+		str:              src,
+		length:           len(src),
+		base:             base,
+		file:             file.NewFile(filename, src, base),
+		comments:         make([]*ast.Comment, 0),
+		commentMap:       &ast.CommentMap{},
+		skippedLineBreak: false,
 	}
 }
 
@@ -184,6 +192,9 @@ func (self *_parser) parse() (*ast.Program, error) {
 	if false {
 		self.errors.Sort()
 	}
+
+	self.addCommentStatements(program, ast.FINAL)
+
 	return program, self.errors.Err()
 }
 
@@ -270,3 +281,63 @@ func (self *_parser) position(idx file.Idx) file.Position {
 
 	return position
 }
+
+// findComments finds the following comments.
+// Comments on the same line will be grouped together and returned.
+// After the first line break, comments will be added as statement comments.
+func (self *_parser) findComments(ignoreLineBreak bool) []*ast.Comment {
+	if self.mode&StoreComments == 0 {
+		return nil
+	}
+	comments := make([]*ast.Comment, 0)
+
+	newline := false
+
+	for self.implicitSemicolon == false || ignoreLineBreak {
+		if self.token != token.COMMENT {
+			break
+		}
+
+		comment := &ast.Comment{
+			Begin:    self.idx,
+			Text:     self.literal,
+			Position: ast.TBD,
+		}
+
+		newline = self.skippedLineBreak || newline
+
+		if newline && !ignoreLineBreak {
+			self.comments = append(self.comments, comment)
+		} else {
+			comments = append(comments, comment)
+		}
+
+		self.next()
+	}
+
+	return comments
+}
+
+// addCommentStatements will add the previously parsed, not positioned comments to the provided node
+func (self *_parser) addCommentStatements(node ast.Node, position ast.CommentPosition) {
+	if len(self.comments) > 0 {
+		self.commentMap.AddComments(node, self.comments, position)
+
+		// Reset comments
+		self.comments = make([]*ast.Comment, 0)
+	}
+}
+
+// fetchComments fetches the current comments, resets the slice and returns the comments
+func (self *_parser) fetchComments() (comments []*ast.Comment) {
+	comments = self.comments
+	self.comments = nil
+
+	return comments
+}
+
+// consumeComments consumes the current comments and appends them to the provided node
+func (self *_parser) consumeComments(node ast.Node, position ast.CommentPosition) {
+	self.commentMap.AddComments(node, self.comments, position)
+	self.comments = nil
+}
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/statement.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/statement.go
index 2059d38563d4f21a1df61b79b1c53ab3c99bdef6..987ac02c1f98023fbbf048281721a82eca1d66e2 100644
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/statement.go
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/parser/statement.go
@@ -7,10 +7,24 @@ import (
 
 func (self *_parser) parseBlockStatement() *ast.BlockStatement {
 	node := &ast.BlockStatement{}
+
+	// Find comments before the leading brace
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node, self.findComments(false), ast.LEADING)
+	}
+
 	node.LeftBrace = self.expect(token.LEFT_BRACE)
 	node.List = self.parseStatementList()
+
+	self.consumeComments(node, ast.FINAL)
+
 	node.RightBrace = self.expect(token.RIGHT_BRACE)
 
+	// Find comments after the trailing brace
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node, self.findComments(false), ast.TRAILING)
+	}
+
 	return node
 }
 
@@ -21,7 +35,14 @@ func (self *_parser) parseEmptyStatement() ast.Statement {
 
 func (self *_parser) parseStatementList() (list []ast.Statement) {
 	for self.token != token.RIGHT_BRACE && self.token != token.EOF {
-		list = append(list, self.parseStatement())
+		if self.token == token.COMMENT {
+			self.parseCommentElement()
+			continue
+		}
+		statement := self.parseStatement()
+		list = append(list, statement)
+
+		self.addCommentStatements(statement, ast.LEADING)
 	}
 
 	return
@@ -77,6 +98,9 @@ func (self *_parser) parseStatement() ast.Statement {
 		// LabelledStatement
 		colon := self.idx
 		self.next() // :
+
+		comments := self.findComments(false)
+
 		label := identifier.Name
 		for _, value := range self.scope.labels {
 			if label == value {
@@ -86,11 +110,17 @@ func (self *_parser) parseStatement() ast.Statement {
 		self.scope.labels = append(self.scope.labels, label) // Push the label
 		statement := self.parseStatement()
 		self.scope.labels = self.scope.labels[:len(self.scope.labels)-1] // Pop the label
-		return &ast.LabelledStatement{
+		exp := &ast.LabelledStatement{
 			Label:     identifier,
 			Colon:     colon,
 			Statement: statement,
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(exp, comments, ast.TRAILING)
+		}
+
+		return exp
 	}
 
 	self.optionalSemicolon()
@@ -107,16 +137,26 @@ func (self *_parser) parseTryStatement() ast.Statement {
 		Body: self.parseBlockStatement(),
 	}
 
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node.Body, self.findComments(true), ast.TRAILING)
+	}
+
 	if self.token == token.CATCH {
 		catch := self.idx
 		self.next()
 		self.expect(token.LEFT_PARENTHESIS)
+		comments := self.findComments(true)
 		if self.token != token.IDENTIFIER {
 			self.expect(token.IDENTIFIER)
 			self.nextStatement()
 			return &ast.BadStatement{From: catch, To: self.idx}
 		} else {
 			identifier := self.parseIdentifier()
+
+			if self.mode&StoreComments != 0 {
+				self.commentMap.AddComments(identifier, comments, ast.LEADING)
+			}
+
 			self.expect(token.RIGHT_PARENTHESIS)
 			node.Catch = &ast.CatchStatement{
 				Catch:     catch,
@@ -124,11 +164,22 @@ func (self *_parser) parseTryStatement() ast.Statement {
 				Body:      self.parseBlockStatement(),
 			}
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(node.Catch, self.findComments(true), ast.TRAILING)
+		}
 	}
 
 	if self.token == token.FINALLY {
 		self.next()
+
+		comments := self.findComments(true)
+
 		node.Finally = self.parseBlockStatement()
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(node.Finally, comments, ast.LEADING)
+		}
 	}
 
 	if node.Catch == nil && node.Finally == nil {
@@ -143,10 +194,15 @@ func (self *_parser) parseFunctionParameterList() *ast.ParameterList {
 	opening := self.expect(token.LEFT_PARENTHESIS)
 	var list []*ast.Identifier
 	for self.token != token.RIGHT_PARENTHESIS && self.token != token.EOF {
+		comments := self.findComments(true)
 		if self.token != token.IDENTIFIER {
 			self.expect(token.IDENTIFIER)
 		} else {
-			list = append(list, self.parseIdentifier())
+			identifier := self.parseIdentifier()
+			if self.mode&StoreComments != 0 {
+				self.commentMap.AddComments(identifier, comments, ast.LEADING)
+			}
+			list = append(list, identifier)
 		}
 		if self.token != token.RIGHT_PARENTHESIS {
 			self.expect(token.COMMA)
@@ -218,12 +274,24 @@ func (self *_parser) parseFunctionBlock(node *ast.FunctionLiteral) {
 func (self *_parser) parseDebuggerStatement() ast.Statement {
 	idx := self.expect(token.DEBUGGER)
 
+	comments := self.findComments(true)
+
 	node := &ast.DebuggerStatement{
 		Debugger: idx,
 	}
 
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node, comments, ast.TRAILING)
+	}
+
 	self.semicolon()
 
+	if !self.skippedLineBreak {
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(node, self.findComments(false), ast.TRAILING)
+		}
+	}
+
 	return node
 }
 
@@ -309,30 +377,77 @@ func (self *_parser) parseSwitchStatement() ast.Statement {
 
 func (self *_parser) parseWithStatement() ast.Statement {
 	self.expect(token.WITH)
+
+	// Find the comments after with
+	comments := self.findComments(true)
+
 	self.expect(token.LEFT_PARENTHESIS)
+
 	node := &ast.WithStatement{
 		Object: self.parseExpression(),
 	}
 	self.expect(token.RIGHT_PARENTHESIS)
 
+	// Add the key comments
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node, comments, ast.KEY)
+	}
+
+	// Find the leading comments for the body
+	comments = self.findComments(true)
+
 	node.Body = self.parseStatement()
 
+	// Add the body comments
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node.Body, comments, ast.LEADING)
+	}
+
+	// Move the trailing comments to the with statement
+	self.commentMap.MoveComments(node.Body, node, ast.TRAILING)
+
 	return node
 }
 
 func (self *_parser) parseCaseStatement() *ast.CaseStatement {
 
+	var comments []*ast.Comment
+
 	node := &ast.CaseStatement{
 		Case: self.idx,
 	}
+
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node, self.findComments(true), ast.LEADING)
+	}
+
+	// Consume current comments
+	self.consumeComments(node, ast.LEADING)
+
 	if self.token == token.DEFAULT {
 		self.next()
 	} else {
 		self.expect(token.CASE)
+
+		comments = self.findComments(true)
+
 		node.Test = self.parseExpression()
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(node.Test, comments, ast.LEADING)
+		}
+
+		comments = self.findComments(true)
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(node.Test, comments, ast.TRAILING)
+		}
 	}
+
 	self.expect(token.COLON)
 
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node.Test, self.findComments(false), ast.TRAILING)
+	}
+
 	for {
 		if self.token == token.EOF ||
 			self.token == token.RIGHT_BRACE ||
@@ -340,8 +455,12 @@ func (self *_parser) parseCaseStatement() *ast.CaseStatement {
 			self.token == token.DEFAULT {
 			break
 		}
-		node.Consequent = append(node.Consequent, self.parseStatement())
+		consequent := self.parseStatement()
+		node.Consequent = append(node.Consequent, consequent)
 
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(consequent, self.findComments(false), ast.TRAILING)
+		}
 	}
 
 	return node
@@ -360,44 +479,84 @@ func (self *_parser) parseForIn(into ast.Expression) *ast.ForInStatement {
 
 	// Already have consumed "<into> in"
 
+	// Comments after the in, before the expression
+	comments := self.findComments(true)
+
 	source := self.parseExpression()
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(source, comments, ast.LEADING)
+	}
+
 	self.expect(token.RIGHT_PARENTHESIS)
 
-	return &ast.ForInStatement{
+	comments = self.findComments(true)
+	body := self.parseIterationStatement()
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(body, comments, ast.LEADING)
+	}
+
+	forin := &ast.ForInStatement{
 		Into:   into,
 		Source: source,
-		Body:   self.parseIterationStatement(),
+		Body:   body,
 	}
+
+	self.commentMap.MoveComments(body, forin, ast.TRAILING)
+
+	return forin
 }
 
 func (self *_parser) parseFor(initializer ast.Expression) *ast.ForStatement {
 
 	// Already have consumed "<initializer> ;"
 
+	comments := self.findComments(true)
+
 	var test, update ast.Expression
 
 	if self.token != token.SEMICOLON {
 		test = self.parseExpression()
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(test, comments, ast.LEADING)
+		}
 	}
 	self.expect(token.SEMICOLON)
 
+	comments = self.findComments(true)
+
 	if self.token != token.RIGHT_PARENTHESIS {
 		update = self.parseExpression()
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(update, comments, ast.LEADING)
+		}
 	}
 	self.expect(token.RIGHT_PARENTHESIS)
 
-	return &ast.ForStatement{
+	comments = self.findComments(true)
+
+	body := self.parseIterationStatement()
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(body, comments, ast.LEADING)
+	}
+
+	forstatement := &ast.ForStatement{
 		Initializer: initializer,
 		Test:        test,
 		Update:      update,
-		Body:        self.parseIterationStatement(),
+		Body:        body,
 	}
+
+	self.commentMap.MoveComments(body, forstatement, ast.TRAILING)
+
+	return forstatement
 }
 
 func (self *_parser) parseForOrForInStatement() ast.Statement {
 	idx := self.expect(token.FOR)
 	self.expect(token.LEFT_PARENTHESIS)
 
+	comments := self.findComments(true)
+
 	var left []ast.Expression
 
 	forIn := false
@@ -435,11 +594,19 @@ func (self *_parser) parseForOrForInStatement() ast.Statement {
 			self.nextStatement()
 			return &ast.BadStatement{From: idx, To: self.idx}
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(left[0], comments, ast.LEADING)
+		}
 		return self.parseForIn(left[0])
 	}
 
 	self.expect(token.SEMICOLON)
-	return self.parseFor(&ast.SequenceExpression{Sequence: left})
+	initializer := &ast.SequenceExpression{Sequence: left}
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(initializer, comments, ast.LEADING)
+	}
+	return self.parseFor(initializer)
 }
 
 func (self *_parser) parseVariableStatement() *ast.VariableStatement {
@@ -447,12 +614,27 @@ func (self *_parser) parseVariableStatement() *ast.VariableStatement {
 	idx := self.expect(token.VAR)
 
 	list := self.parseVariableDeclarationList(idx)
-	self.semicolon()
 
-	return &ast.VariableStatement{
+	statement := &ast.VariableStatement{
 		Var:  idx,
 		List: list,
 	}
+
+	self.commentMap.MoveComments(statement.List[len(statement.List)-1], statement, ast.TRAILING)
+
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(statement, self.findComments(true), ast.TRAILING)
+	}
+
+	self.semicolon()
+
+	if self.skippedLineBreak {
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(statement, self.findComments(false), ast.TRAILING)
+		}
+	}
+
+	return statement
 }
 
 func (self *_parser) parseDoWhileStatement() ast.Statement {
@@ -463,7 +645,13 @@ func (self *_parser) parseDoWhileStatement() ast.Statement {
 	}()
 
 	self.expect(token.DO)
+
+	comments := self.findComments(true)
+
 	node := &ast.DoWhileStatement{}
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node, comments, ast.KEY)
+	}
 	if self.token == token.LEFT_BRACE {
 		node.Body = self.parseBlockStatement()
 	} else {
@@ -471,49 +659,123 @@ func (self *_parser) parseDoWhileStatement() ast.Statement {
 	}
 
 	self.expect(token.WHILE)
+
+	comments = self.findComments(true)
+
 	self.expect(token.LEFT_PARENTHESIS)
 	node.Test = self.parseExpression()
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node.Test, comments, ast.LEADING)
+	}
+
 	self.expect(token.RIGHT_PARENTHESIS)
 
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node.Test, self.findComments(false), ast.TRAILING)
+	}
+
 	return node
 }
 
 func (self *_parser) parseWhileStatement() ast.Statement {
 	self.expect(token.WHILE)
+
+	// Comments after while keyword
+	comments := self.findComments(true)
+
 	self.expect(token.LEFT_PARENTHESIS)
 	node := &ast.WhileStatement{
 		Test: self.parseExpression(),
 	}
+
+	// Add the while comments
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node, comments, ast.KEY)
+	}
+
 	self.expect(token.RIGHT_PARENTHESIS)
+
+	// Finding comments prior to the body
+	comments = self.findComments(true)
+
 	node.Body = self.parseIterationStatement()
 
+	// Adding the comments prior to the body
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node.Body, comments, ast.LEADING)
+	}
+
+	// Move the trailing comments to the while statement
+	self.commentMap.MoveComments(node.Body, node, ast.TRAILING)
+
 	return node
 }
 
 func (self *_parser) parseIfStatement() ast.Statement {
 	self.expect(token.IF)
+
+	comments := self.findComments(true)
+
 	self.expect(token.LEFT_PARENTHESIS)
 	node := &ast.IfStatement{
 		Test: self.parseExpression(),
 	}
+
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node, comments, ast.KEY)
+	}
+
 	self.expect(token.RIGHT_PARENTHESIS)
 
+	comments = self.findComments(true)
+
 	if self.token == token.LEFT_BRACE {
 		node.Consequent = self.parseBlockStatement()
 	} else {
 		node.Consequent = self.parseStatement()
 	}
 
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(node.Consequent, comments, ast.LEADING)
+		self.commentMap.AddComments(node.Consequent, self.findComments(true), ast.TRAILING)
+	}
+
 	if self.token == token.ELSE {
 		self.next()
+		comments = self.findComments(true)
+
 		node.Alternate = self.parseStatement()
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(node.Alternate, comments, ast.LEADING)
+			self.commentMap.AddComments(node.Alternate, self.findComments(false), ast.TRAILING)
+		}
 	}
 
 	return node
 }
 
 func (self *_parser) parseSourceElement() ast.Statement {
-	return self.parseStatement()
+
+	statementComment := self.fetchComments()
+
+	statement := self.parseStatement()
+
+	if self.mode&StoreComments != 0 {
+		self.commentMap.AddComments(statement, statementComment, ast.LEADING)
+	}
+
+	return statement
+}
+
+func (self *_parser) parseCommentElement() {
+	literal := self.literal
+	idx := self.expect(token.COMMENT)
+	self.comments = append(self.comments, &ast.Comment{
+		Begin:    idx,
+		Text:     literal,
+		Position: ast.LEADING,
+	})
 }
 
 func (self *_parser) parseSourceElements() []ast.Statement {
@@ -524,10 +786,19 @@ func (self *_parser) parseSourceElements() []ast.Statement {
 			break
 		}
 
+		if self.token == token.COMMENT {
+			self.parseCommentElement()
+			continue
+		}
+
 		body = append(body, self.parseSourceElement())
 	}
 
 	for self.token != token.EOF {
+		if self.token == token.COMMENT {
+			self.parseCommentElement()
+			continue
+		}
 		body = append(body, self.parseSourceElement())
 	}
 
@@ -546,6 +817,9 @@ func (self *_parser) parseProgram() *ast.Program {
 
 func (self *_parser) parseBreakStatement() ast.Statement {
 	idx := self.expect(token.BREAK)
+
+	breakComments := self.findComments(true)
+
 	semicolon := self.implicitSemicolon
 	if self.token == token.SEMICOLON {
 		semicolon = true
@@ -557,10 +831,16 @@ func (self *_parser) parseBreakStatement() ast.Statement {
 		if !self.scope.inIteration && !self.scope.inSwitch {
 			goto illegal
 		}
-		return &ast.BranchStatement{
+		breakStatement := &ast.BranchStatement{
 			Idx:   idx,
 			Token: token.BREAK,
 		}
+
+		if self.mode&StoreComments != 0 {
+			self.commentMap.AddComments(breakStatement, breakComments, ast.TRAILING)
+		}
+
+		return breakStatement
 	}
 
 	if self.token == token.IDENTIFIER {
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/runtime.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/runtime.go
index 168cb1cde954ffff352df29ff3e6f3c0ce16942b..a998f7acc689309739bdbcd4f0416883094eb7e3 100644
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/runtime.go
+++ b/Godeps/_workspace/src/github.com/robertkrimen/otto/runtime.go
@@ -55,6 +55,7 @@ type _runtime struct {
 	otto         *Otto
 	eval         *_object // The builtin eval, for determine indirect versus direct invocation
 	debugger     func(*Otto)
+	random       func() float64
 
 	labels []string // FIXME
 	lck    sync.Mutex
diff --git a/jsre/jsre.go b/jsre/jsre.go
index a4c9d970be46dd2d334cf28af2e5878a19606020..f4464910de4961e208cfed9e58f79bea0b0cbf12 100644
--- a/jsre/jsre.go
+++ b/jsre/jsre.go
@@ -18,8 +18,11 @@
 package jsre
 
 import (
+	crand "crypto/rand"
+	"encoding/binary"
 	"fmt"
 	"io/ioutil"
+	"math/rand"
 	"sync"
 	"time"
 
@@ -70,6 +73,18 @@ func New(assetPath string) *JSRE {
 	return re
 }
 
+// randomSource returns a pseudo random value generator.
+func randomSource() *rand.Rand {
+	bytes := make([]byte, 8)
+	seed := time.Now().UnixNano()
+	if _, err := crand.Read(bytes); err == nil {
+		seed = int64(binary.LittleEndian.Uint64(bytes))
+	}
+
+	src := rand.NewSource(seed)
+	return rand.New(src)
+}
+
 // This function runs the main event loop from a goroutine that is started
 // when JSRE is created. Use Stop() before exiting to properly stop it.
 // The event loop processes vm access requests from the evalQueue in a
@@ -81,6 +96,9 @@ func New(assetPath string) *JSRE {
 // called from JS through an RPC call.
 func (self *JSRE) runEventLoop() {
 	vm := otto.New()
+	r := randomSource()
+	vm.SetRandomSource(r.Float64)
+
 	registry := map[*jsTimer]*jsTimer{}
 	ready := make(chan *jsTimer)