Merged from PI
authorUnai Martirena <unai.martirena@openbravo.com>
Wed, 11 May 2016 17:18:45 +0200
changeset 29639 5776bfd165d5
parent 29608 e3d34293e490 (current diff)
parent 29638 20100cb9945a (diff)
child 29640 02e361a6af80
Merged from PI
src-db/database/sourcedata/AD_MESSAGE.xml
src-db/database/sourcedata/AD_REF_LIST.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.client.kernel/jsbeautify/jsbeautifier.py	Wed May 11 17:18:45 2016 +0200
@@ -0,0 +1,1089 @@
+#!/usr/bin/env python
+
+import sys
+import getopt
+import re
+
+#
+# Originally written by Einar Lielmanis et al.,
+# Conversion to python by Einar Lielmanis, einar@jsbeautifier.org,
+# MIT licence, enjoy.
+#
+# Python is not my native language, feel free to push things around.
+#
+# Use either from command line (script displays its usage when run
+# without any parameters),
+#
+#
+# or, alternatively, use it as a module:
+#
+#   import jsbeautifier
+#   res = jsbeautifier.beautify('your javascript string')
+#   res = jsbeautifier.beautify_file('some_file.js')
+#
+#  you may specify some options:
+#
+#   opts = jsbeautifier.default_options()
+#   opts.indent_size = 2
+#   res = jsbeautifier.beautify('some javascript', opts)
+#
+#
+# Here are the available options: (read source)
+
+
+class BeautifierOptions:
+    def __init__(self):
+        self.indent_size = 4
+        self.indent_char = ' '
+        self.preserve_newlines = True
+        self.max_preserve_newlines = 10.
+        self.jslint_happy = False
+        self.brace_style = 'collapse'
+        self.keep_array_indentation = False
+        self.indent_level = 0
+
+
+
+    def __repr__(self):
+        return \
+"""indent_size = %d
+indent_char = [%s]
+preserve_newlines = %s
+max_preserve_newlines = %d
+jslint_happy = %s
+brace_style = %s
+keep_array_indentation = %s
+indent_level = %d
+""" % ( self.indent_size,
+        self.indent_char,
+        self.preserve_newlines,
+        self.max_preserve_newlines,
+        self.jslint_happy,
+        self.brace_style,
+        self.keep_array_indentation,
+        self.indent_level)
+
+
+class BeautifierFlags:
+    def __init__(self, mode):
+        self.previous_mode = 'BLOCK'
+        self.mode = mode
+        self.var_line = False
+        self.var_line_tainted = False
+        self.var_line_reindented = False
+        self.in_html_comment = False
+        self.if_line = False
+        self.in_case = False
+        self.eat_next_space = False
+        self.indentation_baseline = -1
+        self.indentation_level = 0
+        self.ternary_depth = 0
+
+
+def default_options():
+    return BeautifierOptions()
+
+
+def beautify(string, opts = default_options() ):
+    b = Beautifier()
+    return b.beautify(string, opts)
+
+
+def beautify_file(file_name, opts = default_options() ):
+
+    if file_name == '-': # stdin
+        f = sys.stdin
+    else:
+        f = open(file_name)
+
+    b = Beautifier()
+    return b.beautify(''.join(f.readlines()), opts)
+
+
+def usage():
+
+    print("""Javascript beautifier (http://jsbeautifier.org/)
+
+Usage: jsbeautifier.py [options] <infile>
+
+    <infile> can be "-", which means stdin.
+
+Input options:
+
+ -i,  --stdin                      read input from stdin
+
+Output options:
+
+ -s,  --indent-size=NUMBER         indentation size. (default 4).
+ -c,  --indent-char=CHAR           character to indent with. (default space).
+ -d,  --disable-preserve-newlines  do not preserve existing line breaks.
+ -j,  --jslint-happy               more jslint-compatible output
+ -b,  --brace-style=collapse       brace style (collapse, expand, end-expand)
+ -k,  --keep-array-indentation     keep array indentation.
+
+Rarely needed options:
+
+ -l,  --indent-level=NUMBER        initial indentation level. (default 0).
+
+ -h,  --help, --usage              prints this help statement.
+
+""");
+
+
+
+
+
+
+class Beautifier:
+
+    def __init__(self, opts = default_options() ):
+
+        self.opts = opts
+        self.blank_state()
+
+    def blank_state(self):
+
+        # internal flags
+        self.flags = BeautifierFlags('BLOCK')
+        self.flag_store = []
+        self.wanted_newline = False
+        self.just_added_newline = False
+        self.do_block_just_closed = False
+
+
+        self.indent_string = self.opts.indent_char * self.opts.indent_size
+        self.last_word = ''              # last TK_WORD seen
+        self.last_type = 'TK_START_EXPR' # last token type
+        self.last_text = ''              # last token text
+        self.last_last_text = ''         # pre-last token text
+
+        self.input = None
+        self.output = []                 # formatted javascript gets built here
+
+        self.whitespace = ["\n", "\r", "\t", " "]
+        self.wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'
+        self.digits = '0123456789'
+        self.punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |= ::'.split(' ');
+
+
+        # Words which always should start on a new line
+        self.line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(',')
+        self.set_mode('BLOCK')
+
+        global parser_pos
+        parser_pos = 0
+
+
+    def beautify(self, s, opts = None ):
+
+        if opts != None:
+            self.opts = opts
+
+
+        if self.opts.brace_style not in ['expand', 'collapse', 'end-expand']:
+            raise(Exception('opts.brace_style must be "expand", "collapse" or "end-expand".'))
+
+        self.blank_state()
+
+        self.input = s
+
+        parser_pos = 0
+        while True:
+            token_text, token_type = self.get_next_token()
+            #print (token_text, token_type, self.flags.mode)
+            if token_type == 'TK_EOF':
+                break
+
+            handlers = {
+                'TK_START_EXPR': self.handle_start_expr,
+                'TK_END_EXPR': self.handle_end_expr,
+                'TK_START_BLOCK': self.handle_start_block,
+                'TK_END_BLOCK': self.handle_end_block,
+                'TK_WORD': self.handle_word,
+                'TK_SEMICOLON': self.handle_semicolon,
+                'TK_STRING': self.handle_string,
+                'TK_EQUALS': self.handle_equals,
+                'TK_OPERATOR': self.handle_operator,
+                'TK_BLOCK_COMMENT': self.handle_block_comment,
+                'TK_INLINE_COMMENT': self.handle_inline_comment,
+                'TK_COMMENT': self.handle_comment,
+                'TK_UNKNOWN': self.handle_unknown,
+            }
+
+            handlers[token_type](token_text)
+
+            self.last_last_text = self.last_text
+            self.last_type = token_type
+            self.last_text = token_text
+
+        sweet_code = re.sub('[\n ]+$', '', ''.join(self.output))
+        if self.opts.indent_level:
+            sweet_code = self.opts.indent_level * self.indent_string + sweet_code
+        return sweet_code
+
+
+
+    def trim_output(self, eat_newlines = False):
+        while len(self.output) \
+              and (
+                  self.output[-1] == ' '\
+                  or self.output[-1] == self.indent_string \
+                  or (eat_newlines and self.output[-1] in ['\n', '\r'])):
+            self.output.pop()
+
+
+    def is_array(self, mode):
+        return mode in ['[EXPRESSION]', '[INDENDED-EXPRESSION]']
+
+
+    def is_expression(self, mode):
+        return mode in ['[EXPRESSION]', '[INDENDED-EXPRESSION]', '(EXPRESSION)']
+
+
+    def append_newline_forced(self):
+        old_array_indentation = self.opts.keep_array_indentation
+        self.opts.keep_array_indentation = False
+        self.append_newline()
+        self.opts.keep_array_indentation = old_array_indentation
+
+    def append_newline(self, ignore_repeated = True):
+
+        self.flags.eat_next_space = False;
+
+        if self.opts.keep_array_indentation and self.is_array(self.flags.mode):
+            return
+
+        self.flags.if_line = False;
+        self.trim_output();
+
+        if len(self.output) == 0:
+            # no newline on start of file
+            return
+
+        if self.output[-1] != '\n' or not ignore_repeated:
+            self.just_added_newline = True
+            self.output.append('\n')
+
+        for i in range(self.flags.indentation_level + self.opts.indent_level):
+            self.output.append(self.indent_string)
+
+        if self.flags.var_line and self.flags.var_line_reindented:
+            if self.opts.indent_char == ' ':
+                # var_line always pushes 4 spaces, so that the variables would be one under another
+                self.output.append('    ')
+            else:
+                self.output.append(self.indent_string)
+
+
+    def append(self, s):
+        if s == ' ':
+            # make sure only single space gets drawn
+            if self.flags.eat_next_space:
+                self.flags.eat_next_space = False
+            elif len(self.output) and self.output[-1] not in [' ', '\n', self.indent_string]:
+                self.output.append(' ')
+        else:
+            self.just_added_newline = False
+            self.flags.eat_next_space = False
+            self.output.append(s)
+
+
+    def indent(self):
+        self.flags.indentation_level = self.flags.indentation_level + 1
+
+
+    def remove_indent(self):
+        if len(self.output) and self.output[-1] == self.indent_string:
+            self.output.pop()
+
+
+    def set_mode(self, mode):
+
+        prev = BeautifierFlags('BLOCK')
+
+        if self.flags:
+            self.flag_store.append(self.flags)
+            prev = self.flags
+
+        self.flags = BeautifierFlags(mode)
+
+        if len(self.flag_store) == 1:
+            self.flags.indentation_level = 0
+        else:
+            self.flags.indentation_level = prev.indentation_level
+            if prev.var_line and prev.var_line_reindented:
+                self.flags.indentation_level = self.flags.indentation_level + 1
+        self.flags.previous_mode = prev.mode
+
+
+    def restore_mode(self):
+        self.do_block_just_closed = self.flags.mode == 'DO_BLOCK'
+        if len(self.flag_store) > 0:
+            self.flags = self.flag_store.pop()
+
+
+    def get_next_token(self):
+
+        global parser_pos
+
+        self.n_newlines = 0
+
+        if parser_pos >= len(self.input):
+            return '', 'TK_EOF'
+
+        self.wanted_newline = False;
+        c = self.input[parser_pos]
+        parser_pos += 1
+
+        keep_whitespace = self.opts.keep_array_indentation and self.is_array(self.flags.mode)
+
+        if keep_whitespace:
+            # slight mess to allow nice preservation of array indentation and reindent that correctly
+            # first time when we get to the arrays:
+            # var a = [
+            # ....'something'
+            # we make note of whitespace_count = 4 into flags.indentation_baseline
+            # so we know that 4 whitespaces in original source match indent_level of reindented source
+            #
+            # and afterwards, when we get to
+            #    'something,
+            # .......'something else'
+            # we know that this should be indented to indent_level + (7 - indentation_baseline) spaces
+
+            whitespace_count = 0
+            while c in self.whitespace:
+                if c == '\n':
+                    self.trim_output()
+                    self.output.append('\n')
+                    self.just_added_newline = True
+                    whitespace_count = 0
+                elif c == '\t':
+                    whitespace_count += 4
+                elif c == '\r':
+                    pass
+                else:
+                    whitespace_count += 1
+
+                if parser_pos >= len(self.input):
+                    return '', 'TK_EOF'
+
+                c = self.input[parser_pos]
+                parser_pos += 1
+
+            if self.flags.indentation_baseline == -1:
+
+                self.flags.indentation_baseline = whitespace_count
+
+            if self.just_added_newline:
+                for i in range(self.flags.indentation_level + 1):
+                    self.output.append(self.indent_string)
+
+                if self.flags.indentation_baseline != -1:
+                    for i in range(whitespace_count - self.flags.indentation_baseline):
+                        self.output.append(' ')
+
+        else: # not keep_whitespace
+            while c in self.whitespace:
+                if c == '\n':
+                    if self.opts.max_preserve_newlines == 0 or self.opts.max_preserve_newlines > self.n_newlines:
+                        self.n_newlines += 1
+
+                if parser_pos >= len(self.input):
+                    return '', 'TK_EOF'
+
+                c = self.input[parser_pos]
+                parser_pos += 1
+
+            if self.opts.preserve_newlines and self.n_newlines > 1:
+                for i in range(self.n_newlines):
+                    self.append_newline(i == 0)
+                    self.just_added_newline = True
+
+            self.wanted_newline = self.n_newlines > 0
+
+
+        if c in self.wordchar:
+            if parser_pos < len(self.input):
+                while self.input[parser_pos] in self.wordchar:
+                    c = c + self.input[parser_pos]
+                    parser_pos += 1
+                    if parser_pos == len(self.input):
+                        break
+
+            # small and surprisingly unugly hack for 1E-10 representation
+            if parser_pos != len(self.input) and self.input[parser_pos] in '+-' \
+               and re.match('^[0-9]+[Ee]$', c):
+
+                sign = self.input[parser_pos]
+                parser_pos += 1
+                t = self.get_next_token()
+                c += sign + t[0]
+                return c, 'TK_WORD'
+
+            if c == 'in': # in is an operator, need to hack
+                return c, 'TK_OPERATOR'
+
+            if self.wanted_newline and \
+               self.last_type != 'TK_OPERATOR' and\
+               self.last_type != 'TK_EQUALS' and\
+               not self.flags.if_line and \
+               (self.opts.preserve_newlines or self.last_text != 'var'):
+                self.append_newline()
+
+            return c, 'TK_WORD'
+
+        if c in '([':
+            return c, 'TK_START_EXPR'
+
+        if c in ')]':
+            return c, 'TK_END_EXPR'
+
+        if c == '{':
+            return c, 'TK_START_BLOCK'
+
+        if c == '}':
+            return c, 'TK_END_BLOCK'
+
+        if c == ';':
+            return c, 'TK_SEMICOLON'
+
+        if c == '/':
+            comment = ''
+            inline_comment = True
+            comment_mode = 'TK_INLINE_COMMENT'
+            if self.input[parser_pos] == '*': # peek /* .. */ comment
+                parser_pos += 1
+                if parser_pos < len(self.input):
+                    while not (self.input[parser_pos] == '*' and \
+                               parser_pos + 1 < len(self.input) and \
+                               self.input[parser_pos + 1] == '/')\
+                          and parser_pos < len(self.input):
+                        c = self.input[parser_pos]
+                        comment += c
+                        if c in '\r\n':
+                            comment_mode = 'TK_BLOCK_COMMENT'
+                        parser_pos += 1
+                        if parser_pos >= len(self.input):
+                            break
+                parser_pos += 2
+                return '/*' + comment + '*/', comment_mode
+            if self.input[parser_pos] == '/': # peek // comment
+                comment = c
+                while self.input[parser_pos] not in '\r\n':
+                    comment += self.input[parser_pos]
+                    parser_pos += 1
+                    if parser_pos >= len(self.input):
+                        break
+                parser_pos += 1
+                if self.wanted_newline:
+                    self.append_newline()
+                return comment, 'TK_COMMENT'
+
+
+
+        if c == "'" or c == '"' or \
+           (c == '/' and ((self.last_type == 'TK_WORD' and self.last_text in ['return', 'do']) or \
+                          (self.last_type in ['TK_COMMENT', 'TK_START_EXPR', 'TK_START_BLOCK', 'TK_END_BLOCK', 'TK_OPERATOR',
+                                              'TK_EQUALS', 'TK_EOF', 'TK_SEMICOLON']))):
+             sep = c
+             esc = False
+             resulting_string = c
+             in_char_class = False
+
+             if parser_pos < len(self.input):
+                if sep == '/':
+                    # handle regexp
+                    in_char_class = False
+                    while esc or in_char_class or self.input[parser_pos] != sep:
+                        resulting_string += self.input[parser_pos]
+                        if not esc:
+                            esc = self.input[parser_pos] == '\\'
+                            if self.input[parser_pos] == '[':
+                                in_char_class = True
+                            elif self.input[parser_pos] == ']':
+                                in_char_class = False
+                        else:
+                            esc = False
+                        parser_pos += 1
+                        if parser_pos >= len(self.input):
+                            # incomplete regex when end-of-file reached
+                            # bail out with what has received so far
+                            return resulting_string, 'TK_STRING'
+                else:
+                    # handle string
+                    while esc or self.input[parser_pos] != sep:
+                        resulting_string += self.input[parser_pos]
+                        if not esc:
+                            esc = self.input[parser_pos] == '\\'
+                        else:
+                            esc = False
+                        parser_pos += 1
+                        if parser_pos >= len(self.input):
+                            # incomplete string when end-of-file reached
+                            # bail out with what has received so far
+                            return resulting_string, 'TK_STRING'
+
+
+             parser_pos += 1
+             resulting_string += sep
+             if sep == '/':
+                 # regexps may have modifiers /regexp/MOD, so fetch those too
+                 while parser_pos < len(self.input) and self.input[parser_pos] in self.wordchar:
+                     resulting_string += self.input[parser_pos]
+                     parser_pos += 1
+             return resulting_string, 'TK_STRING'
+
+        if c == '#':
+
+            # she-bang
+            if len(self.output) == 0 and len(self.input) > 1 and self.input[parser_pos] == '!':
+                resulting_string = c
+                while parser_pos < len(self.input) and c != '\n':
+                    c = self.input[parser_pos]
+                    resulting_string += c
+                    parser_pos += 1
+                self.output.append(resulting_string.strip() + "\n")
+                self.append_newline()
+                return self.get_next_token()
+
+
+            # Spidermonkey-specific sharp variables for circular references
+            # https://developer.mozilla.org/En/Sharp_variables_in_JavaScript
+            # http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935
+            sharp = '#'
+            if parser_pos < len(self.input) and self.input[parser_pos] in self.digits:
+                while True:
+                    c = self.input[parser_pos]
+                    sharp += c
+                    parser_pos += 1
+                    if parser_pos >= len(self.input)  or c == '#' or c == '=':
+                        break
+            if c == '#' or parser_pos >= len(self.input):
+                pass
+            elif self.input[parser_pos] == '[' and self.input[parser_pos + 1] == ']':
+                sharp += '[]'
+                parser_pos += 2
+            elif self.input[parser_pos] == '{' and self.input[parser_pos + 1] == '}':
+                sharp += '{}'
+                parser_pos += 2
+            return sharp, 'TK_WORD'
+
+        if c == '<' and self.input[parser_pos - 1 : parser_pos + 3] == '<!--':
+            parser_pos += 3
+            self.flags.in_html_comment = True
+            return '<!--', 'TK_COMMENT'
+
+        if c == '-' and self.flags.in_html_comment and self.input[parser_pos - 1 : parser_pos + 2] == '-->':
+            self.flags.in_html_comment = False
+            parser_pos += 2
+            if self.wanted_newline:
+                self.append_newline()
+            return '-->', 'TK_COMMENT'
+
+        if c in self.punct:
+            while parser_pos < len(self.input) and c + self.input[parser_pos] in self.punct:
+                c += self.input[parser_pos]
+                parser_pos += 1
+                if parser_pos >= len(self.input):
+                    break
+            if c == '=':
+                return c, 'TK_EQUALS'
+            else:
+                return c, 'TK_OPERATOR'
+        return c, 'TK_UNKNOWN'
+
+
+
+    def handle_start_expr(self, token_text):
+        if token_text == '[':
+            if self.last_type == 'TK_WORD' or self.last_text == ')':
+                if self.last_text in self.line_starters:
+                    self.append(' ')
+                self.set_mode('(EXPRESSION)')
+                self.append(token_text)
+                return
+
+            if self.flags.mode in ['[EXPRESSION]', '[INDENTED-EXPRESSION]']:
+                if self.last_last_text == ']' and self.last_text == ',':
+                    # ], [ goes to a new line
+                    if self.flags.mode == '[EXPRESSION]':
+                        self.flags.mode = '[INDENTED-EXPRESSION]'
+                        if not self.opts.keep_array_indentation:
+                            self.indent()
+                    self.set_mode('[EXPRESSION]')
+                    if not self.opts.keep_array_indentation:
+                        self.append_newline()
+                elif self.last_text == '[':
+                    if self.flags.mode == '[EXPRESSION]':
+                        self.flags.mode = '[INDENTED-EXPRESSION]'
+                        if not self.opts.keep_array_indentation:
+                            self.indent()
+                    self.set_mode('[EXPRESSION]')
+
+                    if not self.opts.keep_array_indentation:
+                        self.append_newline()
+                else:
+                    self.set_mode('[EXPRESSION]')
+            else:
+                self.set_mode('[EXPRESSION]')
+        else:
+            self.set_mode('(EXPRESSION)')
+
+
+        if self.last_text == ';' or self.last_type == 'TK_START_BLOCK':
+            self.append_newline()
+        elif self.last_type in ['TK_END_EXPR', 'TK_START_EXPR', 'TK_END_BLOCK'] or self.last_text == '.':
+            # do nothing on (( and )( and ][ and ]( and .(
+            pass
+        elif self.last_type not in ['TK_WORD', 'TK_OPERATOR']:
+            self.append(' ')
+        elif self.last_word == 'function' or self.last_word == 'typeof':
+            # function() vs function (), typeof() vs typeof ()
+            if self.opts.jslint_happy:
+                self.append(' ')
+        elif self.last_text in self.line_starters or self.last_text == 'catch':
+            self.append(' ')
+
+        self.append(token_text)
+
+
+    def handle_end_expr(self, token_text):
+        if token_text == ']':
+            if self.opts.keep_array_indentation:
+                if self.last_text == '}':
+                    self.remove_indent()
+                    self.append(token_text)
+                    self.restore_mode()
+                    return
+            else:
+                if self.flags.mode == '[INDENTED-EXPRESSION]':
+                    if self.last_text == ']':
+                        self.restore_mode()
+                        self.append_newline()
+                        self.append(token_text)
+                        return
+        self.restore_mode()
+        self.append(token_text)
+
+
+    def handle_start_block(self, token_text):
+        if self.last_word == 'do':
+            self.set_mode('DO_BLOCK')
+        else:
+            self.set_mode('BLOCK')
+
+        if self.opts.brace_style == 'expand':
+            if self.last_type != 'TK_OPERATOR':
+                if self.last_text in ['return', '=']:
+                    self.append(' ')
+                else:
+                    self.append_newline(True)
+
+            self.append(token_text)
+            self.indent()
+        else:
+            if self.last_type not in ['TK_OPERATOR', 'TK_START_EXPR']:
+                if self.last_type == 'TK_START_BLOCK':
+                    self.append_newline()
+                else:
+                    self.append(' ')
+            else:
+                # if TK_OPERATOR or TK_START_EXPR
+                if self.is_array(self.flags.previous_mode) and self.last_text == ',':
+                    if self.last_last_text == '}':
+                        self.append(' ')
+                    else:
+                        self.append_newline()
+            self.indent()
+            self.append(token_text)
+
+
+
+
+
+    def handle_end_block(self, token_text):
+        self.restore_mode()
+        if self.opts.brace_style == 'expand':
+            if self.last_text != '{':
+                self.append_newline()
+        else:
+            if self.last_type == 'TK_START_BLOCK':
+                if self.just_added_newline:
+                    self.remove_indent()
+                else:
+                    # {}
+                    self.trim_output()
+            else:
+                if self.is_array(self.flags.mode) and self.opts.keep_array_indentation:
+                    self.opts.keep_array_indentation = False
+                    self.append_newline()
+                    self.opts.keep_array_indentation = True
+                else:
+                    self.append_newline()
+
+        self.append(token_text)
+
+
+    def handle_word(self, token_text):
+        if self.do_block_just_closed:
+            self.append(' ')
+            self.append(token_text)
+            self.append(' ')
+            self.do_block_just_closed = False
+            return
+
+        if token_text == 'function':
+
+            if self.flags.var_line:
+                self.flags.var_line_reindented = True
+            if (self.just_added_newline or self.last_text == ';') and self.last_text != '{':
+                # make sure there is a nice clean space of at least one blank line
+                # before a new function definition
+                have_newlines = self.n_newlines
+                if not self.just_added_newline:
+                    have_newlines = 0
+                if not self.opts.preserve_newlines:
+                    have_newlines = 1
+                for i in range(2 - have_newlines):
+                    self.append_newline(False)
+
+        if token_text in ['case', 'default']:
+            if self.last_text == ':':
+                self.remove_indent()
+            else:
+                self.flags.indentation_level -= 1
+                self.append_newline()
+                self.flags.indentation_level += 1
+            self.append(token_text)
+            self.flags.in_case = True
+            return
+
+        prefix = 'NONE'
+
+        if self.last_type == 'TK_END_BLOCK':
+            if token_text not in ['else', 'catch', 'finally']:
+                prefix = 'NEWLINE'
+            else:
+                if self.opts.brace_style in ['expand', 'end-expand']:
+                    prefix = 'NEWLINE'
+                else:
+                    prefix = 'SPACE'
+                    self.append(' ')
+        elif self.last_type == 'TK_SEMICOLON' and self.flags.mode in ['BLOCK', 'DO_BLOCK']:
+            prefix = 'NEWLINE'
+        elif self.last_type == 'TK_SEMICOLON' and self.is_expression(self.flags.mode):
+            prefix = 'SPACE'
+        elif self.last_type == 'TK_STRING':
+            prefix = 'NEWLINE'
+        elif self.last_type == 'TK_WORD':
+            if self.last_text == 'else':
+                # eat newlines between ...else *** some_op...
+                # won't preserve extra newlines in this place (if any), but don't care that much
+                self.trim_output(True);
+            prefix = 'SPACE'
+        elif self.last_type == 'TK_START_BLOCK':
+            prefix = 'NEWLINE'
+        elif self.last_type == 'TK_END_EXPR':
+            self.append(' ')
+            prefix = 'NEWLINE'
+
+        if self.flags.if_line and self.last_type == 'TK_END_EXPR':
+            self.flags.if_line = False
+
+        if token_text in self.line_starters:
+            if self.last_text == 'else':
+                prefix = 'SPACE'
+            else:
+                prefix = 'NEWLINE'
+
+        if token_text in ['else', 'catch', 'finally']:
+            if self.last_type != 'TK_END_BLOCK' \
+               or self.opts.brace_style == 'expand' \
+               or self.opts.brace_style == 'end-expand':
+                self.append_newline()
+            else:
+                self.trim_output(True)
+                self.append(' ')
+        elif prefix == 'NEWLINE':
+            if token_text == 'function' and (self.last_type == 'TK_START_EXPR' or self.last_text in '=,'):
+                # no need to force newline on "function" -
+                #   (function...
+                pass
+            elif token_text == 'function' and self.last_text == 'new':
+                self.append(' ')
+            elif self.last_text in ['return', 'throw']:
+                # no newline between return nnn
+                self.append(' ')
+            elif self.last_type != 'TK_END_EXPR':
+                if (self.last_type != 'TK_START_EXPR' or token_text != 'var') and self.last_text != ':':
+                    # no need to force newline on VAR -
+                    # for (var x = 0...
+                    if token_text == 'if' and self.last_word == 'else' and self.last_text != '{':
+                        self.append(' ')
+                    else:
+                        self.flags.var_line = False
+                        self.flags.var_line_reindented = False
+                        self.append_newline()
+            elif token_text in self.line_starters and self.last_text != ')':
+                self.flags.var_line = False
+                self.flags.var_line_reindented = False
+                self.append_newline()
+        elif self.is_array(self.flags.mode) and self.last_text == ',' and self.last_last_text == '}':
+                self.append_newline() # }, in lists get a newline
+        elif prefix == 'SPACE':
+            self.append(' ')
+
+
+        self.append(token_text)
+        self.last_word = token_text
+
+        if token_text == 'var':
+            self.flags.var_line = True
+            self.flags.var_line_reindented = False
+            self.flags.var_line_tainted = False
+
+
+        if token_text == 'if':
+            self.flags.if_line = True
+
+        if token_text == 'else':
+            self.flags.if_line = False
+
+
+    def handle_semicolon(self, token_text):
+        self.append(token_text)
+        self.flags.var_line = False
+        self.flags.var_line_reindented = False
+        if self.flags.mode == 'OBJECT':
+            # OBJECT mode is weird and doesn't get reset too well.
+            self.flags.mode = 'BLOCK'
+
+
+    def handle_string(self, token_text):
+        if self.last_type in ['TK_START_BLOCK', 'TK_END_BLOCK', 'TK_SEMICOLON']:
+            self.append_newline()
+        elif self.last_type == 'TK_WORD':
+            self.append(' ')
+
+        self.append(token_text)
+
+
+    def handle_equals(self, token_text):
+        if self.flags.var_line:
+            # just got an '=' in a var-line, different line breaking rules will apply
+            self.flags.var_line_tainted = True
+
+        self.append(' ')
+        self.append(token_text)
+        self.append(' ')
+
+
+    def handle_operator(self, token_text):
+        space_before = True
+        space_after = True
+
+        if self.flags.var_line and token_text == ',' and self.is_expression(self.flags.mode):
+            # do not break on comma, for ( var a = 1, b = 2
+            self.flags.var_line_tainted = False
+
+        if self.flags.var_line and token_text == ',':
+            if self.flags.var_line_tainted:
+                self.append(token_text)
+                self.flags.var_line_reindented = True
+                self.flags.var_line_tainted = False
+                self.append_newline()
+                return
+            else:
+                self.flags.var_line_tainted = False
+
+        if self.last_text in ['return', 'throw']:
+            # return had a special handling in TK_WORD
+            self.append(' ')
+            self.append(token_text)
+            return
+
+        if token_text == ':' and self.flags.in_case:
+            self.append(token_text)
+            self.append_newline()
+            self.flags.in_case = False
+            return
+
+        if token_text == '::':
+            # no spaces around the exotic namespacing syntax operator
+            self.append(token_text)
+            return
+
+        if token_text == ',':
+            if self.flags.var_line:
+                if self.flags.var_line_tainted:
+                    # This never happens, as it's handled previously, right?
+                    self.append(token_text)
+                    self.append_newline()
+                    self.flags.var_line_tainted = False
+                else:
+                    self.append(token_text)
+                    self.append(' ')
+            elif self.last_type == 'TK_END_BLOCK' and self.flags.mode != '(EXPRESSION)':
+                self.append(token_text)
+                if self.flags.mode == 'OBJECT' and self.last_text == '}':
+                    self.append_newline()
+                else:
+                    self.append(' ')
+            else:
+                if self.flags.mode == 'OBJECT':
+                    self.append(token_text)
+                    self.append_newline()
+                else:
+                    # EXPR or DO_BLOCK
+                    self.append(token_text)
+                    self.append(' ')
+            # comma handled
+            return
+        elif token_text in ['--', '++', '!'] \
+                or (token_text in ['+', '-'] \
+                    and self.last_type in ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']) \
+                or self.last_text in self.line_starters:
+
+            space_before = False
+            space_after = False
+
+            if self.last_text == ';' and self.is_expression(self.flags.mode):
+                # for (;; ++i)
+                #         ^^
+                space_before = True
+
+            if self.last_type == 'TK_WORD' and self.last_text in self.line_starters:
+                space_before = True
+
+            if self.flags.mode == 'BLOCK' and self.last_text in ['{', ';']:
+                # { foo: --i }
+                # foo(): --bar
+                self.append_newline()
+
+        elif token_text == '.':
+            # decimal digits or object.property
+            space_before = False
+
+        elif token_text == ':':
+            if self.flags.ternary_depth == 0:
+                self.flags.mode = 'OBJECT'
+                space_before = False
+            else:
+                self.flags.ternary_depth -= 1
+        elif token_text == '?':
+            self.flags.ternary_depth += 1
+
+        if space_before:
+            self.append(' ')
+
+        self.append(token_text)
+
+        if space_after:
+            self.append(' ')
+
+
+
+    def handle_block_comment(self, token_text):
+
+        lines = token_text.replace('\x0d', '').split('\x0a')
+        # all lines start with an asterisk? that's a proper box comment
+        if not any(l for l in lines[1:] if (l.lstrip())[0] != '*'):
+            self.append_newline()
+            self.append(lines[0])
+            for line in lines[1:]:
+                self.append_newline()
+                self.append(' ' + line.strip())
+        else:
+            # simple block comment: leave intact
+            if len(lines) > 1:
+                # multiline comment starts on a new line
+                self.append_newline()
+                self.trim_output()
+            else:
+                # single line /* ... */ comment stays on the same line
+                self.append(' ')
+            for line in lines:
+                self.append(line)
+                self.append('\n')
+        self.append_newline()
+
+
+    def handle_inline_comment(self, token_text):
+        self.append(' ')
+        self.append(token_text)
+        if self.is_expression(self.flags.mode):
+            self.append(' ')
+        else:
+            self.append_newline_forced()
+
+
+    def handle_comment(self, token_text):
+        if self.wanted_newline:
+            self.append_newline()
+        else:
+            self.append(' ')
+
+        self.append(token_text)
+        self.append_newline_forced()
+
+
+    def handle_unknown(self, token_text):
+        if self.last_text in ['return', 'throw']:
+            self.append(' ')
+
+        self.append(token_text)
+
+
+
+
+
+def main():
+
+    argv = sys.argv[1:]
+
+    try:
+        opts, args = getopt.getopt(argv, "s:c:djbkil:h", ['indent-size=','indent-char=', 'disable-preserve-newlines',
+                                                          'jslint-happy', 'brace-style=',
+                                                          'keep-array-indentation', 'indent-level=', 'help',
+                                                          'usage', 'stdin'])
+    except getopt.GetoptError:
+        usage()
+        sys.exit(2)
+
+    js_options = default_options()
+
+    file = None
+    if len(args) == 1:
+        file = args[0]
+
+    for opt, arg in opts:
+        if opt in ('--keep-array-indentation', '-k'):
+            js_options.keep_array_indentation = True
+        if opt in ('--indent-size', '-s'):
+            js_options.indent_size = int(arg)
+        elif opt in ('--indent-char', '-c'):
+            js_options.indent_char = arg
+        elif opt in ('--disable-preserve_newlines', '-d'):
+            js_options.preserve_newlines = False
+        elif opt in ('--jslint-happy', '-j'):
+            js_options.jslint_happy = True
+        elif opt in ('--brace-style', '-b'):
+            js_options.brace_style = arg
+        elif opt in ('--indent-level', '-l'):
+            js_options.indent_level = int(arg)
+        elif opt in ('--stdin', '-i'):
+            file = '-'
+        elif opt in ('--help', '--usage', '--h'):
+            return usage()
+
+    if file == None:
+        return usage()
+    else:
+        print(beautify_file(file, js_options))
+
+
+
+if __name__ == "__main__":
+    main()
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.client.kernel/jsbeautify/jsbeautify	Wed May 11 17:18:45 2016 +0200
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e
+# Mercurial pre-commit hook for jsbeautify
+
+changedfile=$1
+replaceparam=$2
+./modules/org.openbravo.client.kernel/jsbeautify/jsbeautifier.py --indent-size=2 --jslint-happy "$changedfile" > "$changedfile.beautified"
+if ! diff -Z "$changedfile" "$changedfile.beautified" >/dev/null ; then
+  if [ "$replaceparam" != "replace" ] ; then
+    echo "Beautify Error --> Please, beautify $changedfile";
+    rm -rf "$changedfile.beautified"
+    export ERROR="1"
+  else
+    perl -pe 'chop if eof' "$changedfile.beautified" > "$changedfile"
+    echo "Beautify --> File beautified: $changedfile";
+  fi
+fi
+rm -rf "$changedfile.beautified"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.client.kernel/jsbeautify/jsbeautify-module	Wed May 11 17:18:45 2016 +0200
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e
+# Mercurial pre-commit hook for jsbeautify
+
+changedfile=$1
+replaceparam=$2
+../org.openbravo.client.kernel/jsbeautify/jsbeautifier.py --indent-size=2 --jslint-happy "$changedfile" > "$changedfile.beautified"
+if ! diff -Z "$changedfile" "$changedfile.beautified" >/dev/null ; then
+  if [ "$replaceparam" != "replace" ] ; then
+    echo "Beautify Error --> Please, beautify $changedfile";
+    rm -rf "$changedfile.beautified"
+    export ERROR="1"
+  else
+    perl -pe 'chop if eof' "$changedfile.beautified" > "$changedfile"
+    echo "Beautify --> File beautified: $changedfile";
+  fi
+fi
+rm -rf "$changedfile.beautified"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.client.kernel/jsbeautify/jscheck-btfy	Wed May 11 17:18:45 2016 +0200
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -e
+replaceparam=$1
+if [ "$replaceparam" != "replace" ] ; then
+ echo "Performing jsbeautify check on all js resources"
+else
+ echo "Performing jsbeautify replacement on all js resources"
+fi
+
+files=$(./modules/org.openbravo.client.kernel/jscheck/jsfiles ./modules)
+
+for changedfile in echo $files; do
+  if [ -f "$changedfile" -a -n "$(echo $changedfile | awk '/.js$/')" ]; then
+    source ./modules/org.openbravo.client.kernel/jsbeautify/jsbeautify $changedfile $replaceparam
+  fi
+done
+exit $ERROR
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.client.kernel/jsbeautify/jscheck-btfy-hg	Wed May 11 17:18:45 2016 +0200
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e
+# Mercurial pre-commit hook for jsbeautify
+
+replaceparam=$1
+if [ "$replaceparam" != "replace" ] ; then
+ echo "Performing jsbeautify check on all js resources"
+else
+ echo "Performing jsbeautify replacement on all js resources"
+fi
+
+for changedfile in $(hg st -ma)
+do
+  if [ -f "$changedfile" -a -n "$(echo $changedfile | awk '/.js$/ && ! /^web/')" ]; then
+    source ./modules/org.openbravo.client.kernel/jsbeautify/jsbeautify $changedfile $replaceparam
+  fi
+done
+exit $ERROR
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.client.kernel/jsbeautify/jscheck-btfy-module	Wed May 11 17:18:45 2016 +0200
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e
+replaceparam=$1
+if [ "$replaceparam" != "replace" ] ; then
+ echo "Performing jsbeautify check on all js resources"
+else
+ echo "Performing jsbeautify replacement on all js resources"
+fi
+
+files=$(../org.openbravo.client.kernel/jscheck/jsfiles ./)
+
+for changedfile in echo $(hg st -ma)
+do
+  if [ -f "$changedfile" -a -n "$(echo $changedfile | awk '/.js$/')" ]; then
+  source ../org.openbravo.client.kernel/jsbeautify/jsbeautify-module $changedfile $replaceparam
+  fi
+done
+exit $ERROR
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.client.kernel/jsbeautify/jscheck-btfy-module-hg	Wed May 11 17:18:45 2016 +0200
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -e
+# Mercurial pre-commit hook for jsbeautify
+replaceparam=$1
+if [ "$replaceparam" != "replace" ] ; then
+ echo "Performing jsbeautify check on all js resources"
+else
+ echo "Performing jsbeautify replacement on all js resources"
+fi
+
+for changedfile in $(hg st -ma)
+do
+  if [ -f "$changedfile" -a -n "$(echo $changedfile | awk '/.js$/')" ]; then
+    source ../org.openbravo.client.kernel/jsbeautify/jsbeautify-module $changedfile $replaceparam
+  fi
+done
+exit $ERROR
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.client.kernel/jscheck/jsfiles	Wed May 11 17:18:45 2016 +0200
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# Find js files
+
+find $1 -name '*.js' -and ! -path '*isomorphic*' \
+-and ! -path '*qunit*' -and ! -path '*docs*' \
+-and ! -path '*LAB*' -and ! -path '*benchmark*' \
+-and ! -path '*unittest*' \
+-and ! -path '*postest*' \
+-and ! -path '*xmla4js*' \
+-and ! -path '*VAADIN*' \
+-and ! -path '*saiku*' \
+-and ! -path '*libs*' \
+-and ! -path '*lib*' \
+-and ! -path '*enyo*' \
+-and ! -path '*smartclient*' \
+-and ! -path '*scopeleaks*' \
+-and ! -path '*BigDecimal*'
\ No newline at end of file
--- a/modules/org.openbravo.client.kernel/jslint/jscheck	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.client.kernel/jslint/jscheck	Wed May 11 17:18:45 2016 +0200
@@ -1,16 +1,4 @@
-#!/bin/sh
-echo "Performing jslint check on all js resources"
-find ./modules -name '*.js' -and ! -path '*isomorphic*' \
--and ! -path '*qunit*' -and ! -path '*docs*' \
--and ! -path '*LAB*' -and ! -path '*benchmark*' \
--and ! -path '*unittest*' \
--and ! -path '*postest*' \
--and ! -path '*xmla4js*' \
--and ! -path '*VAADIN*' \
--and ! -path '*saiku*' \
--and ! -path '*libs*' \
--and ! -path '*lib*' \
--and ! -path '*enyo*' \
--and ! -path '*smartclient*' \
--and ! -path '*scopeleaks*' \
--and ! -path '*BigDecimal*' | xargs ./modules/org.openbravo.client.kernel/jslint/jslint || exit 1
+#!/bin/bash
+
+files=$(./modules/org.openbravo.client.kernel/jscheck/jsfiles ./modules)
+echo $files | xargs ./modules/org.openbravo.client.kernel/jslint/jslint || exit 1
--- a/modules/org.openbravo.client.kernel/jslint/jscheck-hg	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.client.kernel/jslint/jscheck-hg	Wed May 11 17:18:45 2016 +0200
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 
 # Mercurial pretxncommit hook
 echo "Performing jslint check on modified js resources"
--- a/modules/org.openbravo.client.kernel/jslint/jscheck-module-hg	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.client.kernel/jslint/jscheck-module-hg	Wed May 11 17:18:45 2016 +0200
@@ -1,17 +1,17 @@
-#!/bin/sh
+#!/bin/bash
 
 # Mercurial pretxncommit hook
 echo "Performing jslint check on modified js resources"
 for i in $(hg log -r $HG_NODE --template '{files}')
 do
-	if [[ $i == *vendor* ]]
-	then
-	  echo "Skipping " $i;
-	else
-	  if [ -f "$i" -a -n "$(echo $i | awk '/.js$/')" ]
-	  then
-	    ../org.openbravo.client.kernel/jslint/jslint-module $i || exit 1
-		fi
+  if [[ $i == *vendor* ]]
+  then
+    echo "Skipping " $i;
+  else
+    if [ -f "$i" -a -n "$(echo $i | awk '/.js$/')" ]
+    then
+      ../org.openbravo.client.kernel/jslint/jslint-module $i || exit 1
+	fi
   fi
 done
 
--- a/modules/org.openbravo.client.kernel/jslint/jslint	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.client.kernel/jslint/jslint	Wed May 11 17:18:45 2016 +0200
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 
 # --browser doesn't work properly in jslint4java 1.4.7
 # adding the global available functions manually: window, unscape, top, alert, escape
--- a/modules/org.openbravo.client.kernel/jslint/jslint-module	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.client.kernel/jslint/jslint-module	Wed May 11 17:18:45 2016 +0200
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 
 # --browser doesn't work properly in jslint4java 1.4.7
 # adding the global available functions manually: window, unscape, top, alert, escape
@@ -7,4 +7,4 @@
 echo "Checking --> $@"
 java -jar ../org.openbravo.client.kernel/lib/runtime/jslint4java-1.4.7.jar \
  --browser --evil --continue --undef \
- --predef window,unescape,escape,top,alert,isc,OB,ok,test,module,expect,same,stop,start,asyncTest,equals,BigDecimal "$@"
+ --predef window,unescape,escape,top,alert,isc,OB,ok,test,module,expect,same,stop,start,asyncTest,equals,BigDecimal "$@"
\ No newline at end of file
--- a/modules/org.openbravo.client.querylist/src/org/openbravo/client/querylist/QueryListDataSource.java	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.client.querylist/src/org/openbravo/client/querylist/QueryListDataSource.java	Wed May 11 17:18:45 2016 +0200
@@ -102,12 +102,12 @@
         accessibleWidgetInForm = isAccessibleWidgetInForm(widgetClass);
       }
       if (!accessibleWidgetInForm
-          && (wi == null || wi.getWidgetClass().getId() != widgetClass.getId())) {
+          && (wi == null || !wi.getWidgetClass().getId().equals(widgetClass.getId()))) {
         // weird stuff: widget class doesn't match widget instance's class, most probably URL is
         // not generated by UI, but user is typing it
         log.error("User " + OBContext.getOBContext().getUser() + " with role "
             + OBContext.getOBContext().getRole() + " is trying to access widget '"
-            + widgetClass.getWidgetTitle() + "' but widget istance doesn't match with class");
+            + widgetClass.getWidgetTitle() + "' but widget instance doesn't match with class");
         throw new OBSecurityException(OBMessageUtils.getI18NMessage("OBCQL_NoAccessToWidget",
             new String[] { widgetClass.getWidgetTitle() }));
       }
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Wed May 11 17:18:45 2016 +0200
@@ -54,6 +54,7 @@
 import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.Property;
+import org.openbravo.base.model.domaintype.BooleanDomainType;
 import org.openbravo.base.model.domaintype.EnumerateDomainType;
 import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.base.session.OBPropertiesProvider;
@@ -89,6 +90,7 @@
 import org.openbravo.model.ad.ui.Tab;
 import org.openbravo.model.ad.ui.Window;
 import org.openbravo.portal.PortalAccessible;
+import org.openbravo.service.db.DalConnectionProvider;
 import org.openbravo.service.json.DefaultJsonDataService;
 import org.openbravo.service.json.JsonConstants;
 import org.openbravo.service.json.JsonUtils;
@@ -142,7 +144,7 @@
 
       SessionInfo.setModuleId(request.getParameter("moduleId"));
       SessionInfo.setCommand(request.getParameter(DataSourceConstants.OPERATION_TYPE_PARAM));
-      SessionInfo.setProcessId(request.getParameter("tabId"));
+      SessionInfo.setProcessId(request.getParameter(JsonConstants.TAB_PARAMETER));
       SessionInfo.setProcessType("W");
 
       super.service(request, response);
@@ -208,7 +210,7 @@
       getRequestContent(request);
     }
     try {
-      if (!hasAccess(request, parameters.get("tabId"))) {
+      if (!hasAccess(request, parameters.get(JsonConstants.TAB_PARAMETER))) {
         throw new OBUserException("AccessTableNoView");
       }
 
@@ -236,10 +238,9 @@
           try {
             OBContext.setAdminMode();
             try {
-              Window window = parameters.get(JsonConstants.TAB_PARAMETER) == null
-                  || parameters.get(JsonConstants.TAB_PARAMETER).equals("undefined") ? null : OBDal
-                  .getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
-                  .getWindow();
+              Window window = JsonUtils.isValueEmpty(parameters.get(JsonConstants.TAB_PARAMETER)) ? null
+                  : OBDal.getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
+                      .getWindow();
               String encoding = Preferences.getPreferenceValue("OBSERDS_CSVTextEncoding", true,
                   OBContext.getOBContext().getCurrentClient(), OBContext.getOBContext()
                       .getCurrentOrganization(), OBContext.getOBContext().getUser(), OBContext
@@ -304,6 +305,7 @@
     Map<String, DecimalFormat> formats = new HashMap<String, DecimalFormat>();
     int clientUTCOffsetMiliseconds;
     TimeZone clientTimeZone;
+    Window windowToCsv = null;
 
     public QueryJSONWriterToCSV(HttpServletRequest request, HttpServletResponse response,
         Map<String, String> parameters, Entity entity) {
@@ -312,9 +314,9 @@
         response.setHeader("Content-Disposition", "attachment; filename=ExportedData.csv");
         writer = response.getWriter();
         VariablesSecureApp vars = new VariablesSecureApp(request);
-        Window window = parameters.get(JsonConstants.TAB_PARAMETER) == null
-            || parameters.get(JsonConstants.TAB_PARAMETER).equals("undefined") ? null : OBDal
-            .getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER)).getWindow();
+        Window window = JsonUtils.isValueEmpty(parameters.get(JsonConstants.TAB_PARAMETER)) ? null
+            : OBDal.getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
+                .getWindow();
         try {
           prefDecimalSeparator = Preferences.getPreferenceValue("OBSERDS_CSVDecimalSeparator",
               true, OBContext.getOBContext().getCurrentClient(), OBContext.getOBContext()
@@ -370,8 +372,7 @@
         }
 
         fieldProperties = new ArrayList<String>();
-        if (parameters.get("viewState") != null
-            && !parameters.get("viewState").toString().equals("undefined")) {
+        if (!JsonUtils.isValueEmpty(parameters.get("viewState"))) {
           String viewStateO = parameters.get("viewState");
           String viewStateWithoutParenthesis = viewStateO.substring(1, viewStateO.length() - 1);
           JSONObject viewState = new JSONObject(viewStateWithoutParenthesis);
@@ -463,6 +464,11 @@
               numericCols.add(propKey);
             }
 
+            // save current window to get preference properly
+            if (prop.getDomainType() instanceof BooleanDomainType) {
+              windowToCsv = window;
+            }
+
             if (!(prop.getDomainType() instanceof EnumerateDomainType)) {
               continue;
             }
@@ -554,6 +560,8 @@
         }
 
         boolean isFirst = true;
+        boolean shouldCheckTranslation = false;
+        boolean preferenceCalculateFirst = true;
         while (itKeys.hasNext()) {
           String key = (String) itKeys.next();
           if (key.endsWith(JsonConstants.IDENTIFIER)) {
@@ -621,6 +629,22 @@
             SimpleDateFormat timeFormat = JsonUtils.createTimeFormatWithoutGMTOffset();
             timeFormat.setLenient(true);
             keyValue = timeFormat.format(clientTimezoneDate);
+          } else if (keyValue instanceof Boolean && keyValue != null) {
+            // Calculate if it is needed translate YesNo reference in export to csv.
+            if (preferenceCalculateFirst == true) {
+              shouldCheckTranslation = getValueShouldCheckTranslationPreference();
+              preferenceCalculateFirst = false;
+            }
+            if (shouldCheckTranslation) {
+              String userLanguage = OBContext.getOBContext().getLanguage().getLanguage();
+              if (keyValue.toString().equals("true")) {
+                keyValue = Utility.messageBD(new DalConnectionProvider(false), "OBUISC_Yes",
+                    userLanguage);
+              } else if (keyValue.toString().equals("false")) {
+                keyValue = Utility.messageBD(new DalConnectionProvider(false), "OBUISC_No",
+                    userLanguage);
+              }
+            }
           }
 
           if (keyValue != null && !keyValue.toString().equals("null")) {
@@ -638,6 +662,18 @@
       }
     }
 
+    private boolean getValueShouldCheckTranslationPreference() {
+      boolean shouldCheck = false;
+      try {
+        shouldCheck = "Y".equals(Preferences.getPreferenceValue("AllowExportCSV_YesNoTranslated",
+            true, OBContext.getOBContext().getCurrentClient(), OBContext.getOBContext()
+                .getCurrentOrganization(), OBContext.getOBContext().getUser(), OBContext
+                .getOBContext().getRole(), windowToCsv));
+      } catch (PropertyException prefNotDefined) {
+      }
+      return shouldCheck;
+    }
+
     private Date convertFromLocalToClientTimezone(Date localDate) {
 
       Date UTCDate = convertFromLocalToUTCTimezone(localDate);
@@ -701,10 +737,9 @@
       try {
         String csvMessage = null;
         try {
-          Window window = parameters.get(JsonConstants.TAB_PARAMETER) == null
-              || parameters.get(JsonConstants.TAB_PARAMETER).equals("undefined") ? null : OBDal
-              .getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
-              .getWindow();
+          Window window = JsonUtils.isValueEmpty(parameters.get(JsonConstants.TAB_PARAMETER)) ? null
+              : OBDal.getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
+                  .getWindow();
           csvMessage = Preferences.getPreferenceValue(property, true, OBContext.getOBContext()
               .getCurrentClient(), OBContext.getOBContext().getCurrentOrganization(), OBContext
               .getOBContext().getUser(), OBContext.getOBContext().getRole(), window);
@@ -764,7 +799,7 @@
     setSessionInfo();
 
     try {
-      if (!hasAccess(request, parameters.get("tabId"))) {
+      if (!hasAccess(request, parameters.get(JsonConstants.TAB_PARAMETER))) {
         throw new OBUserException("AccessTableNoView");
       }
 
@@ -797,7 +832,7 @@
       if (!checkSetParameters(request, response, parameters)) {
         return;
       }
-      if (!hasAccess(request, parameters.get("tabId"))) {
+      if (!hasAccess(request, parameters.get(JsonConstants.TAB_PARAMETER))) {
         throw new OBUserException("AccessTableNoView");
       }
 
@@ -836,7 +871,7 @@
     final Map<String, String> parameters = getParameterMap(request);
     setSessionInfo();
     try {
-      if (!hasAccess(request, parameters.get("tabId"))) {
+      if (!hasAccess(request, parameters.get(JsonConstants.TAB_PARAMETER))) {
         throw new OBUserException("AccessTableNoView");
       }
 
@@ -998,7 +1033,7 @@
    */
   private boolean hasAccess(HttpServletRequest req, String tabId) {
     try {
-      if (tabId == null || tabId.isEmpty()) {
+      if (JsonUtils.isValueEmpty(tabId)) {
         return true;
       }
       VariablesSecureApp vars = new VariablesSecureApp(req);
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DefaultDataSourceService.java	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DefaultDataSourceService.java	Wed May 11 17:18:45 2016 +0200
@@ -155,7 +155,7 @@
       }
 
       final String whereClause;
-      if (parameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE) != null
+      if (StringUtils.isNotBlank(parameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE))
           && !parameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE).equals("null")) {
         whereClause = parameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE) + " and (";
       } else {
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/TreeDatasourceService.java	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/TreeDatasourceService.java	Wed May 11 17:18:45 2016 +0200
@@ -139,9 +139,15 @@
 
   @Override
   public void checkEditDatasourceAccess(Map<String, String> parameter) {
-    Entity theEntity = getEntity();
-    if (!hasAccess(theEntity, null, false)) {
-      throw new OBException(OBMessageUtils.messageBD("AccessTableNoView"));
+    final OBContext obContext = OBContext.getOBContext();
+    String tableId = parameter.get("referencedTableId");
+    try {
+      Entity treeEntity = ModelProvider.getInstance().getEntityByTableId(tableId);
+      if (treeEntity != null) {
+        obContext.getEntityAccessChecker().checkWritableAccess(treeEntity);
+      }
+    } catch (OBSecurityException e) {
+      handleExceptionUnsecuredDSAccess(e);
     }
   }
 
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonConstants.java	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonConstants.java	Wed May 11 17:18:45 2016 +0200
@@ -128,4 +128,7 @@
   public static final String WHERE_CLAUSE_HAS_BEEN_CHECKED = "whereClauseHasBeenChecked";
   public static final String WINDOW_ID = "windowId";
   public static final String DATASOURCE_NAME = "dataSourceName";
+
+  public static final String UNDEFINED = "undefined";
+  public static final String NULL = "null";
 }
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonUtils.java	Thu May 05 18:44:19 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonUtils.java	Wed May 11 17:18:45 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -25,6 +25,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
@@ -391,4 +392,18 @@
     }
   }
 
+  /**
+   * Returns whether a JSON value is empty. The following values are considered as empty:
+   * <ul>
+   * <li>An empty string
+   * <li>{@code null}
+   * <li>{@code "null"} literal
+   * <li>{@code "undefined"} literal
+   * </ul>
+   */
+  public static boolean isValueEmpty(String value) {
+    return StringUtils.isEmpty(value) || JsonConstants.UNDEFINED.equals(value)
+        || JsonConstants.NULL.equals(value);
+  }
+
 }
--- a/src-db/database/model/functions/M_INVENTORY_LISTUPDATE.xml	Thu May 05 18:44:19 2016 +0200
+++ b/src-db/database/model/functions/M_INVENTORY_LISTUPDATE.xml	Wed May 11 17:18:45 2016 +0200
@@ -19,7 +19,7 @@
   * parts created by ComPiere are Copyright (C) ComPiere, Inc.;
   * All Rights Reserved.
   * Contributor(s): Openbravo SLU
-  * Contributions are Copyright (C) 2001-2015 Openbravo, S.L.U.
+  * Contributions are Copyright (C) 2001-2016 Openbravo, S.L.U.
   *
   * Specifically, this derivative work is based upon the following Compiere
   * file and version.
@@ -100,7 +100,8 @@
   */
   IF(NOT END_PROCESS) THEN
     v_ResultStr:='UpdatingLine';
-    DELETE FROM M_InventoryLine
+    UPDATE M_InventoryLine
+    SET QtyBook = 0, QuantityOrderBook = 0
       WHERE M_Inventory_ID=v_Record_ID
         AND (NOT EXISTS
         (SELECT *
@@ -122,10 +123,6 @@
           AND (s.QTYORDERONHAND = 0 OR s.QTYORDERONHAND IS NULL)
         ))
     ;
-    rowcount:=SQL%ROWCOUNT;
-    IF(rowcount<>0) THEN
-      v_Message:='@Deleted@=' || rowcount || ', ';  
-    END IF;
     UPDATE M_InventoryLine
       SET QtyBook=
       (SELECT QtyOnHand
--- a/src-db/database/model/triggers/M_COSTING_TRG.xml	Thu May 05 18:44:19 2016 +0200
+++ b/src-db/database/model/triggers/M_COSTING_TRG.xml	Wed May 11 17:18:45 2016 +0200
@@ -15,11 +15,12 @@
 * under the License.
 * The Original Code is Openbravo ERP.
 * The Initial Developer of the Original Code is Openbravo SLU
-* All portions are Copyright (C) 2012 Openbravo SLU
+* All portions are Copyright (C) 2012-2016 Openbravo SLU
 * All Rights Reserved.
 * Contributor(s):  ______________________________________.
 ************************************************************************/
 v_count NUMBER;
+v_relateddocs BOOLEAN;
 BEGIN
   IF AD_isTriggerEnabled()='N' THEN RETURN;
   END IF;
@@ -31,17 +32,30 @@
     IF(v_count>0 and (:new.costtype = 'AV' or :new.costtype = 'ST' or :new.costtype = 'AVO')) then
       RAISE_APPLICATION_ERROR(-20000, '@CostMigratedInstance@');
     END IF;
-  ELSIF (DELETING) THEN
+
+  ELSIF (UPDATING OR DELETING) THEN
     IF (:OLD.ISPERMANENT = 'Y') THEN
-      RAISE_APPLICATION_ERROR(-20000, '@CannotDeletePermanentCost@');
-    END IF;
-  ELSIF (UPDATING) THEN
-    IF (:OLD.ISPERMANENT = 'Y' 
-        AND (:OLD.COST <> :NEW.COST
-             OR :OLD.DATEFROM <> :NEW.DATEFROM)) THEN
-      RAISE_APPLICATION_ERROR(-20000, '@CannotModifyPermanentCost@');
+      SELECT count(*)
+      INTO v_count
+      FROM dual
+      WHERE EXISTS ( SELECT 1 FROM C_OrderLine WHERE m_product_id = :old.m_product_id )
+      OR EXISTS ( SELECT 1 FROM C_InvoiceLine WHERE m_product_id = :old.m_product_id )
+      OR EXISTS ( SELECT 1 FROM M_InventoryLine WHERE m_product_id = :old.m_product_id )
+      OR EXISTS ( SELECT 1 FROM M_MovementLine WHERE m_product_id = :old.m_product_id )
+      OR EXISTS ( SELECT 1 FROM M_InoutLine WHERE m_product_id = :old.m_product_id )
+      OR EXISTS ( SELECT 1 FROM M_ProductionLine WHERE m_product_id = :old.m_product_id )
+      OR EXISTS ( SELECT 1 FROM M_Internal_ConsumptionLine WHERE m_product_id = :old.m_product_id );
+
+      IF (v_count > 0) THEN
+        IF (UPDATING AND (:OLD.COST <> :NEW.COST OR :OLD.DATEFROM <> :NEW.DATEFROM)) THEN
+          RAISE_APPLICATION_ERROR(-20000, '@CannotModifyPermanentCost@');
+        ELSIF (DELETING) THEN
+          RAISE_APPLICATION_ERROR(-20000, '@CannotDeletePermanentCost@');
+        END IF;
+      END IF;
     END IF;
   END IF;
+
 END M_COSTING_TRG
 ]]></body>
     </trigger>
--- a/src-db/database/sourcedata/AD_MESSAGE.xml	Thu May 05 18:44:19 2016 +0200
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml	Wed May 11 17:18:45 2016 +0200
@@ -26653,6 +26653,18 @@
 <!--E54B403F2B0944E6A68D06661BD7F47E-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--E54B403F2B0944E6A68D06661BD7F47E--></AD_MESSAGE>
 
+<!--E5591DEB3EF44C7493DAA1A7A4429105--><AD_MESSAGE>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <AD_MESSAGE_ID><![CDATA[E5591DEB3EF44C7493DAA1A7A4429105]]></AD_MESSAGE_ID>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <VALUE><![CDATA[OPSWSCounterDay]]></VALUE>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <MSGTEXT><![CDATA[Current Web Services calls]]></MSGTEXT>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--E5591DEB3EF44C7493DAA1A7A4429105--></AD_MESSAGE>
+
 <!--E584531278034B1BA298C7CEBB58EAD2--><AD_MESSAGE>
 <!--E584531278034B1BA298C7CEBB58EAD2-->  <AD_MESSAGE_ID><![CDATA[E584531278034B1BA298C7CEBB58EAD2]]></AD_MESSAGE_ID>
 <!--E584531278034B1BA298C7CEBB58EAD2-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -26834,6 +26846,18 @@
 <!--E7EBD616ABA7417DB1759D8B7E901405-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--E7EBD616ABA7417DB1759D8B7E901405--></AD_MESSAGE>
 
+<!--E7EBD96FEE9A4B9790F47EB089F72888--><AD_MESSAGE>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <AD_MESSAGE_ID><![CDATA[E7EBD96FEE9A4B9790F47EB089F72888]]></AD_MESSAGE_ID>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <VALUE><![CDATA[OPSCurrentConcurrentUsers]]></VALUE>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <MSGTEXT><![CDATA[Current concurrent users]]></MSGTEXT>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--E7EBD96FEE9A4B9790F47EB089F72888--></AD_MESSAGE>
+
 <!--E83760BF3C4E4BE9BEEE76CD6CBE734F--><AD_MESSAGE>
 <!--E83760BF3C4E4BE9BEEE76CD6CBE734F-->  <AD_MESSAGE_ID><![CDATA[E83760BF3C4E4BE9BEEE76CD6CBE734F]]></AD_MESSAGE_ID>
 <!--E83760BF3C4E4BE9BEEE76CD6CBE734F-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_REF_LIST.xml	Thu May 05 18:44:19 2016 +0200
+++ b/src-db/database/sourcedata/AD_REF_LIST.xml	Wed May 11 17:18:45 2016 +0200
@@ -8897,6 +8897,17 @@
 <!--3946D07DF63C47E7A11BFADCF160D6B6-->  <SEQNO><![CDATA[20]]></SEQNO>
 <!--3946D07DF63C47E7A11BFADCF160D6B6--></AD_REF_LIST>
 
+<!--39FF39F25DD84390B4617D66E52C08EE--><AD_REF_LIST>
+<!--39FF39F25DD84390B4617D66E52C08EE-->  <AD_REF_LIST_ID><![CDATA[39FF39F25DD84390B4617D66E52C08EE]]></AD_REF_LIST_ID>
+<!--39FF39F25DD84390B4617D66E52C08EE-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--39FF39F25DD84390B4617D66E52C08EE-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--39FF39F25DD84390B4617D66E52C08EE-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--39FF39F25DD84390B4617D66E52C08EE-->  <VALUE><![CDATA[AllowExportCSV_YesNoTranslated]]></VALUE>
+<!--39FF39F25DD84390B4617D66E52C08EE-->  <NAME><![CDATA[Allow Export to CSV YesNo translated]]></NAME>
+<!--39FF39F25DD84390B4617D66E52C08EE-->  <AD_REFERENCE_ID><![CDATA[A26BA480E2014707B47257024C3CBFF7]]></AD_REFERENCE_ID>
+<!--39FF39F25DD84390B4617D66E52C08EE-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--39FF39F25DD84390B4617D66E52C08EE--></AD_REF_LIST>
+
 <!--3A38B5315B64459793BF256CEB6703B4--><AD_REF_LIST>
 <!--3A38B5315B64459793BF256CEB6703B4-->  <AD_REF_LIST_ID><![CDATA[3A38B5315B64459793BF256CEB6703B4]]></AD_REF_LIST_ID>
 <!--3A38B5315B64459793BF256CEB6703B4-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-test/src/org/openbravo/test/AllWebserviceTests.java	Thu May 05 18:44:19 2016 +0200
+++ b/src-test/src/org/openbravo/test/AllWebserviceTests.java	Wed May 11 17:18:45 2016 +0200
@@ -33,6 +33,7 @@
 import org.openbravo.test.datasource.TestComboDatasource;
 import org.openbravo.test.datasource.FetchDSNoActiveEntityObjects;
 import org.openbravo.test.datasource.TestNoteDatasource;
+import org.openbravo.test.datasource.EmptyStringWhereAndFilterClauseParameter;
 import org.openbravo.test.security.ExplicitCrossOrganizationReference;
 import org.openbravo.test.datasource.DataSourceSecurity;
 import org.openbravo.test.webservice.JSONWebServices;
@@ -72,6 +73,7 @@
     WSWithNoActiveDalObjects.class, //
     FetchDSNoActiveEntityObjects.class, //
     ExplicitCrossOrganizationReference.class, //
-    DataSourceSecurity.class })
+    DataSourceSecurity.class, //
+    EmptyStringWhereAndFilterClauseParameter.class })
 public class AllWebserviceTests {
 }
--- a/src-test/src/org/openbravo/test/costing/TestCosting.java	Thu May 05 18:44:19 2016 +0200
+++ b/src-test/src/org/openbravo/test/costing/TestCosting.java	Wed May 11 17:18:45 2016 +0200
@@ -4093,6 +4093,9 @@
       // Run price correction background
       runPriceBackground();
 
+      // Add sleep to avoid assert errors
+      Thread.sleep(1000);
+
       // Create goods shipment, run costing background, post it and assert it
       ShipmentInOut goodsShipment2 = createGoodsShipment(product, price4, quantity3, day5);
 
--- a/src-test/src/org/openbravo/test/datasource/DataSourceSecurity.java	Thu May 05 18:44:19 2016 +0200
+++ b/src-test/src/org/openbravo/test/datasource/DataSourceSecurity.java	Wed May 11 17:18:45 2016 +0200
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -74,6 +75,9 @@
   private static final String ID_TESTING = "11";
   private static final Object PROD_RESERVATION = "DA7FC1BB3BA44EC48EC1AB9C74168CED";
 
+  private static final String OPERATION_FETCH = "fetch";
+  private static final String OPERATION_UPDATE = "update";
+
   private RoleType role;
   private DataSource dataSource;
   private int expectedResponseStatus;
@@ -92,147 +96,235 @@
     }
   }
 
+  private enum JSONObjectURL {
+    // Move node in Account Tree
+    MOVEMENT_NODE(
+        "?_skinVersion=Default&_create=true&Constants_FIELDSEPARATOR=$&_new=true"
+            + "&_contextUrl=http://localhost:8080/openbravo&Constants_IDENTIFIER=_identifier"
+            + "&_startRow=0&_endRow=200&referencedTableId=188&parentRecordId=56E65CF592BD4DAF8A8A879810646266&tabId=132"
+            + "&_selectedProperties=['searchKey','name','elementLevel','accountType','showValueCondition','summaryLevel']"
+            + "&@FinancialMgmtElement.client@=23C59575B9CF467C9620760EB255B389"
+            + "&@FinancialMgmtElement.id@=56E65CF592BD4DAF8A8A879810646266"
+            + "&@FinancialMgmtElement.organization@=B843C30461EA4501935CB1D125C9C25A&@FinancialMgmtElement.type@=A"
+            + "&@FinancialMgmtElementValue.organization@=B843C30461EA4501935CB1D125C9C25A"
+            + "&@FinancialMgmtElementValue.client@=23C59575B9CF467C9620760EB255B389"
+            + "&@FinancialMgmtElementValue.accountingElement@=56E65CF592BD4DAF8A8A879810646266"
+            + "&@FinancialMgmtElementValue.id@=A45B7570F9BE4A69A3BF53CFEBB29FC0&dropIndex=2"
+            + "&nextNodeId=FF30CF29CE614360AF85020438BFE328&isc_dataFormat=json&prevNodeId=C3FE5804602E481FAEDCA5D4D71B6CF",
+        createJsonObjectForNodeMovement()), //
+    NO_APPLIED("", "");
+
+    private String url;
+    private String content;
+
+    private JSONObjectURL(String url, String content) {
+      this.url = url;
+      this.content = content;
+    }
+
+    private static String createJsonObjectForNodeMovement() {
+      JSONObject dataObject = new JSONObject();
+      JSONObject oldValuesJSON = new JSONObject();
+      JSONObject contentJson = new JSONObject();
+      try {
+        dataObject.put("_identifier", "P - PATRIMONIO NETO Y PASIVO");
+        dataObject.put("_entityName", "FinancialMgmtElementValue");
+        dataObject.put("$ref", "FinancialMgmtElementValue/C3FE5804602E481FAEDCA5D4D71B6CF3");
+        dataObject.put("id", "C3FE5804602E481FAEDCA5D4D71B6CF3");
+        dataObject.put("client", "23C59575B9CF467C9620760EB255B389");
+        dataObject.put("parentId", "-1");
+        dataObject.put("organization", "B843C30461EA4501935CB1D125C9C25A");
+        dataObject.put("searchKey", "A");
+        dataObject.put("accountingElement", "56E65CF592BD4DAF8A8A879810646266");
+        dataObject.put("nodeId", "A45B7570F9BE4A69A3BF53CFEBB29FC0");
+        dataObject.put("seqno", "210");
+
+        oldValuesJSON.put("_identifier", "A - ACTIVO");
+        oldValuesJSON.put("_entityName", "FinancialMgmtElementValue");
+        oldValuesJSON.put("$ref", "FinancialMgmtElementValue/A45B7570F9BE4A69A3BF53CFEBB29FC0");
+        oldValuesJSON.put("id", "A45B7570F9BE4A69A3BF53CFEBB29FC0");
+        oldValuesJSON.put("client", "23C59575B9CF467C9620760EB255B389");
+        oldValuesJSON.put("organization", "B843C30461EA4501935CB1D125C9C25A");
+        oldValuesJSON.put("organization", "B843C30461EA4501935CB1D125C9C25A");
+        oldValuesJSON.put("searchKey", "A");
+        oldValuesJSON.put("name", "ACTIVO");
+        oldValuesJSON.put("accountingElement", "56E65CF592BD4DAF8A8A879810646266");
+        oldValuesJSON.put("nodeId", "A45B7570F9BE4A69A3BF53CFEBB29FC0");
+
+        contentJson.put("dataSource",
+            "D2F94DC86DEC48D69E4BFCE59DC670CF_1462265510526_1462271742157");
+        contentJson.put("operationType", "update");
+        contentJson.put("data", dataObject);
+        contentJson.put("oldValues", oldValuesJSON);
+      } catch (JSONException e) {
+        e.printStackTrace();
+      }
+      return contentJson.toString();
+    }
+  }
+
   @SuppressWarnings("serial")
   private enum DataSource {
-    Order("Order"), //
-    Alert("DB9F062472294F12A0291A7BD203F922"), //
-    ProductByPriceAndWarehouse("ProductByPriceAndWarehouse", new HashMap<String, String>() {
-      {
-        try {
-          put("_selectorDefinitionId", "2E64F551C7C4470C80C29DBA24B34A5F");
-          put("filterClass", "org.openbravo.userinterface.selector.SelectorDataSourceFilter");
-          put("_sortBy", "_identifier");
-          put("_requestType", "Window");
-          put("_distinct", "productPrice");
+    Order("Order", JSONObjectURL.NO_APPLIED, OPERATION_FETCH), //
+    Alert("DB9F062472294F12A0291A7BD203F922", JSONObjectURL.NO_APPLIED, OPERATION_FETCH), //
+    ProductByPriceAndWarehouse("ProductByPriceAndWarehouse", JSONObjectURL.NO_APPLIED,
+        OPERATION_FETCH, new HashMap<String, String>() {
+          {
+            try {
+              put("_selectorDefinitionId", "2E64F551C7C4470C80C29DBA24B34A5F");
+              put("filterClass", "org.openbravo.userinterface.selector.SelectorDataSourceFilter");
+              put("_sortBy", "_identifier");
+              put("_requestType", "Window");
+              put("_distinct", "productPrice");
 
-          // To reproduce this problem is important not to add the targetProperty parameter. For
-          // this reason targetProperty=null.
-          put("_inpTableId", "293");
-          put("_textMatchStyle", "substring");
+              // To reproduce this problem is important not to add the targetProperty parameter. For
+              // this reason targetProperty=null.
+              put("_inpTableId", "293");
+              put("_textMatchStyle", "substring");
 
-          // Filter selector
-          JSONObject criteria = new JSONObject();
-          criteria.put("fieldName", "productPrice$priceListVersion$_identifier");
-          criteria.put("operator", "iContains");
-          criteria.put("value", "Tarifa");
-          put("criteria", criteria.toString());
-        } catch (Exception ignore) {
-        }
-      }
-    }), //
-    PropertySelector("83B60C4C19AE4A9EBA947B948C5BA04D", new HashMap<String, String>() {
-      {
-        // Property selector invocation from Windows > Tab > Field > Property field
-        put("_selectorDefinitionId", "387D9FFC48A74054835C5DF6E6FD08F7");
-        put("inpadTableId", "259");
-        put("inpTabId", "107");
-        put("targetProperty", "property");
-      }
-    }), //
-    ManageVariants("6654D607F650425A9DFF7B6961D54920", new HashMap<String, String>() {
-      {
-        put("@Product.id@", ID_TESTING);
-      }
-    }), //
-    Note("090A37D22E61FE94012E621729090048", new HashMap<String, String>() {
-      {
-        // Note of a record in Windows, Tabs and Fields.
-        String criteria = "{\"fieldName\":\"table\",\"operator\":\"equals\",\"value\":\""
-            + TABLE_WINDOWS_TABS_FIELDS_ID
-            + "\"}__;__{\"fieldName\":\"record\",\"operator\":\"equals\",\"value\":\""
-            + RECORD_OF_WINDOWS_TABS_FIELDS_ID + "\"}";
-        String entityName = "OBUIAPP_Note";
-        put("criteria", criteria);
-        put("_entityName", entityName);
-      }
-    }), //
-    ProductCharacteristics("BE2735798ECC4EF88D131F16F1C4EC72"), //
-    Combo("ComboTableDatasourceService", new HashMap<String, String>() {
-      {
-        // Sales Order > Payment Terms
-        put("fieldId", "1099");
-      }
-    }), //
-    CustomQuerySelectorDatasource("F8DD408F2F3A414188668836F84C21AF",
+              // Filter selector
+              JSONObject criteria = new JSONObject();
+              criteria.put("fieldName", "productPrice$priceListVersion$_identifier");
+              criteria.put("operator", "iContains");
+              criteria.put("value", "Tarifa");
+              put("criteria", criteria.toString());
+            } catch (Exception ignore) {
+            }
+          }
+        }), //
+    PropertySelector("83B60C4C19AE4A9EBA947B948C5BA04D", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
         new HashMap<String, String>() {
           {
+            // Property selector invocation from Windows > Tab > Field > Property field
+            put("_selectorDefinitionId", "387D9FFC48A74054835C5DF6E6FD08F7");
+            put("inpadTableId", "259");
+            put("inpTabId", "107");
+            put("targetProperty", "property");
+          }
+        }), //
+    ManageVariants("6654D607F650425A9DFF7B6961D54920", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            put("@Product.id@", ID_TESTING);
+          }
+        }), //
+    Note("090A37D22E61FE94012E621729090048", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Note of a record in Windows, Tabs and Fields.
+            String criteria = "{\"fieldName\":\"table\",\"operator\":\"equals\",\"value\":\""
+                + TABLE_WINDOWS_TABS_FIELDS_ID
+                + "\"}__;__{\"fieldName\":\"record\",\"operator\":\"equals\",\"value\":\""
+                + RECORD_OF_WINDOWS_TABS_FIELDS_ID + "\"}";
+            String entityName = "OBUIAPP_Note";
+            put("criteria", criteria);
+            put("_entityName", entityName);
+          }
+        }), //
+    ProductCharacteristics("BE2735798ECC4EF88D131F16F1C4EC72", JSONObjectURL.NO_APPLIED,
+        OPERATION_FETCH), //
+    Combo("ComboTableDatasourceService", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Sales Order > Payment Terms
+            put("fieldId", "1099");
+          }
+        }), //
+    CustomQuerySelectorDatasource("F8DD408F2F3A414188668836F84C21AF", JSONObjectURL.NO_APPLIED,
+        OPERATION_FETCH, new HashMap<String, String>() {
+          {
             // Sales Invoice > Selector Business Partner
             put("_selectorDefinitionId", "862F54CB1B074513BD791C6789F4AA42");
             put("inpTableId", "318");
             put("targetProperty", "businessPartner");
           }
         }), //
-    CustomQuerySelectorDatasourceProcess("ADList", new HashMap<String, String>() {
-      {
-        // Sales Order > Add Payment process > Selector Action Regarding Document
-        put("_selectorDefinitionId", "41B3A5EA61AB46FBAF4567E3755BA190");
-        put("_processDefinitionId", "9BED7889E1034FE68BD85D5D16857320");
-        put("targetProperty", "businessPartner");
-      }
-    }), //
-    SelectorGLItemDatasource("FinancialMgmtGLItem", new HashMap<String, String>() {
-      {
-        // Payment In > Add Details process > GLItem section > Selector GLItem
-        put("_selectorDefinitionId", "9FAD469CE4414A25974CF45C0AD22D35");
-        put("inpTableId", "D1A97202E832470285C9B1EB026D54E2");
-        put("targetProperty", "gLItem");
-      }
-    }), //
-    QuickLaunch("99B9CC42FDEA4CA7A4EE35BC49D61E0E"), //
-    QuickCreate("C17951F970E942FD9F3771B7BE91D049"), //
-    HQLDataSource("3C1148C0AB604DE1B51B7EA4112C325F", new HashMap<String, String>() {
-      {
-        // Invocation from Sales Order > Add Payment process > Credit to Use.
-        put("tableId", "58AF4D3E594B421A9A7307480736F03E");
-      }
-    }), //
-    ADTree("90034CAE96E847D78FBEF6D38CB1930D", new HashMap<String, String>() {
-      {
-        // Organization tree view.
-        put("referencedTableId", "155");
-        put("tabId", "143");
-        String selectedPro = "[\"searchKey\",\"name\",\"description\",\"active\",\"summaryLevel\",\"socialName\",\"organizationType\",\"currency\",\"allowPeriodControl\",\"calendar\"]";
-        put("_selectedProperties", selectedPro);
-      }
-    }), //
-    AccountTree("D2F94DC86DEC48D69E4BFCE59DC670CF", new HashMap<String, String>() {
-      {
-        // Account tree > Element value > Open tree view.
-        put("referencedTableId", "188");
-        put("tabId", "132");
-        String selectedPro = "[\"searchKey\",\"name\",\"elementLevel\",\"accountType\",\"showValueCondition\",\"summaryLevel\"]";
-        put("_selectedProperties", selectedPro);
-        put("@FinancialMgmtElement.client@", CLIENT);
-        put("@FinancialMgmtElement.id@", "56E65CF592BD4DAF8A8A879810646266");
-        put("@FinancialMgmtElement.organization@", "B843C30461EA4501935CB1D125C9C25A");
-      }
-    }), //
-    StockReservations("2F5B70D7F12E4F5C8FE20D6F17D69ECF", new HashMap<String, String>() {
-      {
-        // Manage Stock from Stock Reservations
-        put("@MaterialMgmtReservation.id@", ID_TESTING);
-      }
-    }), //
-    QueryList("DD17275427E94026AD721067C3C91C18", new HashMap<String, String>() {
-      {
-        // Query List Widget > Best Sellers
-        put("widgetId", "CD1B06C4ED974B5F905A5A01B097DF4E");
-      }
-    });
+    CustomQuerySelectorDatasourceProcess("ADList", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Sales Order > Add Payment process > Selector Action Regarding Document
+            put("_selectorDefinitionId", "41B3A5EA61AB46FBAF4567E3755BA190");
+            put("_processDefinitionId", "9BED7889E1034FE68BD85D5D16857320");
+            put("targetProperty", "businessPartner");
+          }
+        }), //
+    SelectorGLItemDatasource("FinancialMgmtGLItem", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Payment In > Add Details process > GLItem section > Selector GLItem
+            put("_selectorDefinitionId", "9FAD469CE4414A25974CF45C0AD22D35");
+            put("inpTableId", "D1A97202E832470285C9B1EB026D54E2");
+            put("targetProperty", "gLItem");
+          }
+        }), //
+    QuickLaunch("99B9CC42FDEA4CA7A4EE35BC49D61E0E", JSONObjectURL.NO_APPLIED, OPERATION_FETCH), //
+    QuickCreate("C17951F970E942FD9F3771B7BE91D049", JSONObjectURL.NO_APPLIED, OPERATION_FETCH), //
+    HQLDataSource("3C1148C0AB604DE1B51B7EA4112C325F", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Invocation from Sales Order > Add Payment process > Credit to Use.
+            put("tableId", "58AF4D3E594B421A9A7307480736F03E");
+          }
+        }), //
+    ADTree("90034CAE96E847D78FBEF6D38CB1930D", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Organization tree view.
+            put("referencedTableId", "155");
+            put("tabId", "143");
+            String selectedPro = "[\"searchKey\",\"name\",\"description\",\"active\",\"summaryLevel\",\"socialName\",\"organizationType\",\"currency\",\"allowPeriodControl\",\"calendar\"]";
+            put("_selectedProperties", selectedPro);
+          }
+        }), //
+    AccountTree("D2F94DC86DEC48D69E4BFCE59DC670CF", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Account tree > Element value > Open tree view.
+            put("referencedTableId", "188");
+            put("tabId", "132");
+            String selectedPro = "[\"searchKey\",\"name\",\"elementLevel\",\"accountType\",\"showValueCondition\",\"summaryLevel\"]";
+            put("_selectedProperties", selectedPro);
+            put("@FinancialMgmtElement.client@", CLIENT);
+            put("@FinancialMgmtElement.id@", "56E65CF592BD4DAF8A8A879810646266");
+            put("@FinancialMgmtElement.organization@", "B843C30461EA4501935CB1D125C9C25A");
+          }
+        }), //
+    StockReservations("2F5B70D7F12E4F5C8FE20D6F17D69ECF", JSONObjectURL.NO_APPLIED,
+        OPERATION_FETCH, new HashMap<String, String>() {
+          {
+            // Manage Stock from Stock Reservations
+            put("@MaterialMgmtReservation.id@", ID_TESTING);
+          }
+        }), //
+    QueryList("DD17275427E94026AD721067C3C91C18", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Query List Widget > Best Sellers
+            put("widgetId", "CD1B06C4ED974B5F905A5A01B097DF4E");
+          }
+        }), //
+    AccountTreeMovement("D2F94DC86DEC48D69E4BFCE59DC670CF", JSONObjectURL.MOVEMENT_NODE,
+        OPERATION_UPDATE);
 
     private String ds;
+    private JSONObjectURL urlAndJson;
+    private String operation;
     private Map<String, String> params;
 
-    private DataSource(String ds) {
+    private DataSource(String ds, JSONObjectURL urlAndJson, String operation) {
       this.ds = ds;
+      this.urlAndJson = urlAndJson;
+      this.operation = operation;
+
       params = new HashMap<String, String>();
-      params.put("_operationType", "fetch");
+      params.put("_operationType", operation);
       params.put("_startRow", "0");
       params.put("_endRow", "1");
     }
 
-    private DataSource(String ds, Map<String, String> extraParams) {
-      this(ds);
+    private DataSource(String ds, JSONObjectURL urlAndJson, String operation,
+        Map<String, String> extraParams) {
+      this(ds, urlAndJson, operation);
       params.putAll(extraParams);
     }
   }
@@ -293,6 +385,9 @@
       // Selector into a datasource into a P&E Window.
       testCases.add(new Object[] { type, DataSource.SelectorGLItemDatasource,
           accessForAdminAndSystemOnly });
+
+      // Moving a tree node : https://issues.openbravo.com/view.php?id=32833
+      testCases.add(new Object[] { type, DataSource.AccountTreeMovement, accessForAdminOnly });
     }
     // testing a problem detected in how properties are initialized.
     testCases.add(new Object[] { RoleType.ADMIN_ROLE, DataSource.ProductByPriceAndWarehouse,
@@ -373,10 +468,21 @@
   public void fetchShouldBeAllowedOnlyIfRoleIsGranted() throws Exception {
     OBContext.setOBContext(CONTEXT_USER);
     changeProfile(role.roleId, LANGUAGE_ID, role.orgId, WAREHOUSE_ID);
+
     JSONObject jsonResponse = null;
-    jsonResponse = fetchDataSource();
+    if (dataSource.operation.equals(OPERATION_FETCH)) {
+      jsonResponse = fetchDataSource();
+    } else if (dataSource.operation.equals(OPERATION_UPDATE)) {
+      jsonResponse = updateDataSource();
+    }
     assertThat("Request status", jsonResponse.getInt("status"), is(expectedResponseStatus));
+  }
 
+  private JSONObject updateDataSource() throws Exception {
+    String responseUpdate = doRequest("/org.openbravo.service.datasource/" + dataSource.ds
+        + dataSource.urlAndJson.url, dataSource.urlAndJson.content, 200, "PUT", "application/json");
+
+    return new JSONObject(responseUpdate).getJSONObject("response");
   }
 
   private JSONObject fetchDataSource() throws Exception {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/src/org/openbravo/test/datasource/EmptyStringWhereAndFilterClauseParameter.java	Wed May 11 17:18:45 2016 +0200
@@ -0,0 +1,72 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License. 
+ * The Original Code is Openbravo ERP. 
+ * The Initial Developer of the Original Code is Openbravo SLU 
+ * All portions are Copyright (C)2016 Openbravo SLU 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.test.datasource;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.junit.Test;
+import org.openbravo.service.json.JsonConstants;
+
+/**
+ * This test is for the https://issues.openbravo.com/view.php?id=32912 issue. With these datasource
+ * parameters, the WHERE_AND_FILTER_CLAUSE parameter is the empty string and that was the case that
+ * was failing. This test checks that the request to the datasource is correct and the response is
+ * 0, which is the successful request status.
+ * 
+ * @author Naroa Iriarte
+ * 
+ */
+public class EmptyStringWhereAndFilterClauseParameter extends BaseDataSourceTestDal {
+  private Map<String, String> params;
+
+  public EmptyStringWhereAndFilterClauseParameter() {
+    params = new HashMap<String, String>();
+    params.put("_targetRecordId", "17435FB915B14A93B51F3A6375B12BEE");
+    params.put("_filterByParentProperty", "priceList");
+    params.put("windowId", "146");
+    params.put("tabId", "238");
+    params.put("_operationType", "fetch");
+    params.put("_startRow", "0");
+    params.put("_endRow", "100");
+  }
+
+  @Test
+  public void datasourceRequestStatusShouldBeSuccessful() throws Exception {
+    String datasourceResponse = getDataSourceResponse();
+    JSONObject jsonResponse = new JSONObject(datasourceResponse);
+    assertThat("The request status should be successful.", getStatus(jsonResponse),
+        is(String.valueOf(JsonConstants.RPCREQUEST_STATUS_SUCCESS)));
+  }
+
+  private String getDataSourceResponse() throws Exception {
+    String response = doRequest("/org.openbravo.service.datasource/" + "PricingPriceListVersion",
+        params, 200, "POST");
+    return response;
+  }
+
+  private String getStatus(JSONObject jsonResponse) throws JSONException {
+    return jsonResponse.getJSONObject("response").get("status").toString();
+  }
+}
--- a/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java	Thu May 05 18:44:19 2016 +0200
+++ b/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java	Wed May 11 17:18:45 2016 +0200
@@ -432,12 +432,16 @@
         UsageAudit.auditActionNoDal(this, vars1, this.getClass().getName(),
             System.currentTimeMillis() - t);
       } else {
-        if ((strPopUp != null && !strPopUp.equals("")) || (classInfo.type.equals("S")))
+        if ((strPopUp != null && !strPopUp.equals("")) || classInfo.type.equals("S")) {
           bdErrorGeneralPopUp(request, response,
               Utility.messageBD(this, "Error", variables.getLanguage()),
               Utility.messageBD(this, "AccessTableNoView", variables.getLanguage()));
-        else
+        } else {
           bdError(request, response, "AccessTableNoView", vars1.getLanguage());
+        }
+        String roleStr = "".equals(vars1.getRole()) ? "" : " (" + vars1.getRole() + ")";
+        log4j
+            .warn("Role" + roleStr + " tried to access ungranted resource with ID " + classInfo.id);
       }
     } catch (final ServletException ex) {
       log4j.error("Error captured: ", ex);
--- a/src/org/openbravo/dal/security/EntityAccessChecker.java	Thu May 05 18:44:19 2016 +0200
+++ b/src/org/openbravo/dal/security/EntityAccessChecker.java	Wed May 11 17:18:45 2016 +0200
@@ -668,10 +668,8 @@
         + SELECTOR_REFERENCE + "' and f.tab.id in(" + tabs + ")";
     @SuppressWarnings("unchecked")
     final List<Reference> references = SessionHandler.getInstance().createQuery(hql).list();
-    if (!references.isEmpty()) {
-      for (Reference ref : references) {
-        addEntitiesOfSelectorReference(mp, ref);
-      }
+    for (Reference ref : references) {
+      addEntitiesOfSelectorReference(mp, ref);
     }
   }
 
--- a/src/org/openbravo/erpCommon/obps/ActivationKey.java	Thu May 05 18:44:19 2016 +0200
+++ b/src/org/openbravo/erpCommon/obps/ActivationKey.java	Wed May 11 17:18:45 2016 +0200
@@ -1126,21 +1126,6 @@
     return lastRequestTime.compareTo(lastValidPingTime) < 0;
   }
 
-  /**
-   * Returns the number of current active sessions
-   */
-  private int getActiveSessions(String currentSession) {
-    OBCriteria<Session> obCriteria = OBDal.getInstance().createCriteria(Session.class);
-    obCriteria.add(Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true));
-    obCriteria.add(Restrictions.not(Restrictions.in(Session.PROPERTY_LOGINSTATUS,
-        NO_CU_SESSION_TYPES)));
-
-    if (currentSession != null && !currentSession.equals("")) {
-      obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSession));
-    }
-    return obCriteria.count();
-  }
-
   private int getActiveSessionsForNamedUser(String currentSession, String username) {
     OBCriteria<Session> obCriteria = OBDal.getInstance().createCriteria(Session.class);
     obCriteria.add(Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true));
@@ -1223,6 +1208,11 @@
           sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSConcurrentUsersWarn", lang))
               .append("</td><td>").append(getProperty("limituserswarn")).append("</td></tr>");
         }
+
+        sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSCurrentConcurrentUsers", lang))
+            .append("</td><td>");
+        sb.append(getActiveSessions(null));
+        sb.append("</td></tr>");
       }
 
       sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSInstanceNo", lang))
@@ -1238,11 +1228,23 @@
       sb.append(getWSExplanation(conn, lang));
       sb.append("</td></tr>");
 
+      sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSWSCounterDay", lang))
+          .append("</td><td>");
+      sb.append(getNumberWSDayCounter());
+      sb.append("</td></tr>");
+
       sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSPOSLimitation", lang))
           .append("</td><td>");
       sb.append(getPOSTerminalsExplanation());
       sb.append("</td></tr>");
 
+      for (ModuleLicenseRestrictions.AdditionalInfo addInfo : getAdditionalMessageInfo()) {
+        sb.append("<tr><td>").append(Utility.messageBD(conn, addInfo.getKey(), lang))
+            .append("</td><td>");
+        sb.append(addInfo.getValue());
+        sb.append("</td></tr>");
+      }
+
     } else {
       sb.append(Utility.messageBD(conn, "OPSNonActiveInstance", lang));
     }
@@ -1345,6 +1347,32 @@
   }
 
   /**
+   * get all additional messages to be printed in Instance Activation window.
+   */
+  private List<ModuleLicenseRestrictions.AdditionalInfo> getAdditionalMessageInfo() {
+    List<ModuleLicenseRestrictions.AdditionalInfo> additionalInfo = new ArrayList<ModuleLicenseRestrictions.AdditionalInfo>();
+    for (ModuleLicenseRestrictions moduleRestriction : getModuleLicenseRestrictions()) {
+      additionalInfo.addAll(moduleRestriction.getAdditionalMessage());
+    }
+    return additionalInfo;
+  }
+
+  /**
+   * Returns the number of current active sessions
+   */
+  private int getActiveSessions(String currentSession) {
+    OBCriteria<Session> obCriteria = OBDal.getInstance().createCriteria(Session.class);
+    obCriteria.add(Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true));
+    obCriteria.add(Restrictions.not(Restrictions.in(Session.PROPERTY_LOGINSTATUS,
+        NO_CU_SESSION_TYPES)));
+
+    if (currentSession != null && !currentSession.equals("")) {
+      obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSession));
+    }
+    return obCriteria.count();
+  }
+
+  /**
    * Same as {@link ActivationKey#getSubscribedModules()} with the includeDisabled parameter. When
    * this parameter is true, disabled modules are returned with the DISABLED status, other way they
    * are returned with the status they would have if they were not disabled.
@@ -1882,16 +1910,21 @@
     initWsCountTime = getDayAt0(new Date());
     OBContext.setAdminMode();
     try {
-      OBCriteria<Session> qLogins = OBDal.getInstance().createCriteria(Session.class);
-      qLogins.add(Restrictions.eq(Session.PROPERTY_LOGINSTATUS, "WS"));
-      qLogins.add(Restrictions.ge(Session.PROPERTY_CREATIONDATE, initWsCountTime));
-      wsDayCounter = qLogins.count();
+      wsDayCounter = getNumberWSDayCounter();
       log.info("Initialized ws count to " + wsDayCounter + " from " + initWsCountTime);
     } finally {
       OBContext.restorePreviousMode();
     }
   }
 
+  private int getNumberWSDayCounter() {
+    Date date = getDayAt0(new Date());
+    OBCriteria<Session> qLogins = OBDal.getInstance().createCriteria(Session.class);
+    qLogins.add(Restrictions.eq(Session.PROPERTY_LOGINSTATUS, "WS"));
+    qLogins.add(Restrictions.ge(Session.PROPERTY_CREATIONDATE, date));
+    return qLogins.count();
+  }
+
   private void initializeWsCounter() {
     StringBuilder hql = new StringBuilder();
     hql.append("select min(creationDate)\n");
--- a/src/org/openbravo/erpCommon/obps/ModuleLicenseRestrictions.java	Thu May 05 18:44:19 2016 +0200
+++ b/src/org/openbravo/erpCommon/obps/ModuleLicenseRestrictions.java	Wed May 11 17:18:45 2016 +0200
@@ -11,13 +11,15 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2015 Openbravo SLU 
+ * All portions are Copyright (C) 2015-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
  */
 package org.openbravo.erpCommon.obps;
 
+import java.util.List;
+
 import javax.enterprise.context.ApplicationScoped;
 
 import org.openbravo.erpCommon.obps.ActivationKey.LicenseRestriction;
@@ -49,6 +51,33 @@
   /** Provides the HTML to be injected in Instance Activation window to perform additional actions */
   public String getInstanceActivationExtraActionsHtml(XmlEngine xmlEngine);
 
+  /**
+   * Provides a mechanism to returns an extra message. This information will be shown in Instance
+   * Activation window.
+   */
+  public List<AdditionalInfo> getAdditionalMessage();
+
+  /**
+   * Holder for additional messages. The key is used for retrieves a message from ad_message table.
+   */
+  public static class AdditionalInfo {
+    private String key;
+    private String value;
+
+    public AdditionalInfo(String key, String value) {
+      this.key = key;
+      this.value = value;
+    }
+
+    public String getKey() {
+      return key;
+    }
+
+    public String getValue() {
+      return value;
+    }
+  }
+
   public enum MsgSeverity {
     WARN("Warning"), ERROR("Error");