def do_scan(self, line):
        """
        scan [:tablename] [--batch=#] [-{max}] [--count|-c] [--array|-a] [+filter_attribute:filter_value] [attributes,...]

        if filter_value contains '=' it's interpreted as {conditional}={value} where condtional is:

            eq (equal value)
            ne {value} (not equal value)
            le (less or equal then value)
            lt (less then value)
            ge (greater or equal then value)
            gt (greater then value)
            :exists (value exists)
            :nexists (value does not exists)
            contains (contains value)
            ncontains (does not contains value)
            begin (attribute begins with value)
            between (between value1 and value2 - use: between=value1,value2)

        otherwise the value must fully match (equal attribute)
        """

        table, line = self.get_table_params(line)
        args = self.getargs(line)

        scan_filter = {}
        count = False
        as_array = False
        max_size = None
        batch_size = None
        start = None

        while args:
            arg = args[0]

            if arg.startswith('+'):
                args.pop(0)
                filter_name, filter_value = arg[1:].split(':', 1)

                if filter_value.startswith("begin="):
                    filter_cond = BEGINS_WITH(self.get_typed_value(filter_name, filter_value[6:]))
                elif filter_value.startswith("eq="):
                    filter_cond = EQ(self.get_typed_value(filter_name, filter_value[3:]))
                elif filter_value.startswith("ne="):
                    filter_cond = NE(self.get_typed_value(filter_name, filter_value[3:]))
                elif filter_value.startswith("le="):
                    filter_cond = LE(self.get_typed_value(filter_name, filter_value[3:]))
                elif filter_value.startswith("lt="):
                    filter_cond = LT(self.get_typed_value(filter_name, filter_value[3:]))
                elif filter_value.startswith("ge="):
                    filter_cond = GE(self.get_typed_value(filter_name, filter_value[3:]))
                elif filter_value.startswith("gt="):
                    filter_cond = GT(self.get_typed_value(filter_name, filter_value[3:]))
                elif filter_value == ":exists":
                    filter_cond = NOT_NULL()
                elif filter_value == ":nexists":
                    filter_cond = NULL()
                elif filter_value.startswith("contains="):
                    filter_cond = CONTAINS(self.get_typed_value(filter_name, filter_value[9:]))
                elif filter_value.startswith("between="):
                    parts = filter_value[8:].split(",", 1)
                    filter_cond = BETWEEN(self.get_typed_value(parts[0]), self.get_typed_value(filter_name, parts[1]))
                else:
                    filter_cond = EQ(self.get_typed_value(filter_name, filter_value))

                scan_filter[filter_name] = filter_cond

            elif arg.startswith('--batch='):
                args.pop(0)
                batch_size = int(arg[8:])

            elif arg.startswith('--max='):
                args.pop(0)
                max_size = int(arg[6:])

            elif arg.startswith('--start='):
                args.pop(0)
                start = (arg[8:], )

            elif arg == '--next':
                args.pop(0)
                if self.next_key:
                    start = self.next_key
                else:
                    print "no next"
                    return

            elif arg in ['--array', '-a']:
                args.pop(0)
                as_array = True

            elif arg in ['--count', '-c']:
                args.pop(0)
                count = True

            elif arg[0] == '-' and arg[1:].isdigit():
                args.pop(0)
                max_size = int(arg[1:])

            elif arg == '--':
                args.pop(0)
                break

            elif arg.startswith('-'):
                args.pop(0)
                print "invalid argument: %s" % arg
                break

            else:
                break

        attr_keys = args[0].split(",") if args else None
        attrs = list(set(attr_keys)) if attr_keys else None

        #print "scan filter:%s attributes:%s limit:%s max:%s count:%s" % (scan_filter, attrs, batch_size, max, count)

        result = table.scan(scan_filter=scan_filter, attributes_to_get=attrs, request_limit=batch_size, max_results=max_size, count=count, exclusive_start_key=start)

        if count:
            print "count: %s/%s" % (result.scanned_count, result.count)
            self.next_key = None
        else:
            if as_array and attr_keys:
                self.print_iterator_array(result, attr_keys)
            else:
                self.print_iterator(result)

            self.next_key = result.last_evaluated_key

        if self.consumed:
            print "consumed units:", result.consumed_units