from __future__ import (absolute_import, division, print_function)

from owscapable.util import nspath_eval
from owscapable.namespaces import Namespaces
from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime

from dateutil import parser
from datetime import timedelta

from owscapable.etree import etree

def get_namespaces():
    ns = Namespaces()
    return ns.get_namespaces(["swe20", "xlink"])
namespaces = get_namespaces()

def nspv(path):
    return nspath_eval(path, namespaces)

def make_pair(string, cast=None):
    if string is None:
        return None

    string = string.split(" ")
    if cast is not None:
        try:
            string = map(lambda x: cast(x), string)
        except:
            print("Could not cast pair to correct type.  Setting to an empty tuple!")
            string = ""

    return tuple(string)

def get_uom(element):

    uom = testXMLAttribute(element, "code")
    if uom is None:
        uom = testXMLAttribute(element, nspv("xlink:href"))
    return uom

def get_boolean(value):
    if value is None:
        return None
    if value is True or value.lower() in ["yes","true"]:
        return True
    elif value is False or value.lower() in ["no","false"]:
        return False
    else:
        return None

def get_int(value):
    try:
        return int(value)
    except:
        return None

def get_float(value):
    try:
        return float(value)
    except:
        return None

AnyScalar    = map(lambda x: nspv(x), ["swe20:Boolean", "swe20:Count", "swe20:Quantity", "swe20:Time", "swe20:Category", "swe20:Text"])
AnyNumerical = map(lambda x: nspv(x), ["swe20:Count", "swe20:Quantity", "swe20:Time"])
AnyRange     = map(lambda x: nspv(x), ["swe20:QuantityRange", "swe20:TimeRange", "swe20:CountRange", "swe20:CategoryRange"])

class NamedObject(object):
    def __init__(self, element):
        # No call to super(), the type object will process that.
        self.name           = testXMLAttribute(element, "name")
        try:
            self.content    = eval(element[-1].tag.split("}")[-1])(element[-1])
        except IndexError:
            self.content    = None
        except BaseException:
            raise

    # Revert to the content if attribute does not exists
    def __getattr__(self, name):
        return getattr(self.content, name)

class AbstractSWE(object):
    def __init__(self, element):
        # Attributes
        self.id             = testXMLAttribute(element,"id")   # string, optional

        # Elements
        self.extention      = []                            # anyType, min=0, max=X

class AbstractSWEIdentifiable(AbstractSWE):
    def __init__(self, element):
        super(AbstractSWEIdentifiable, self).__init__(element)
        # Elements
        self.identifier     = testXMLValue(element.find(nspv("swe20:identifier")))    # anyURI, min=0
        self.label          = testXMLValue(element.find(nspv("swe20:label")))         # string, min=0
        self.description    = testXMLValue(element.find(nspv("swe20:description")))   # string, min=0

class AbstractDataComponent(AbstractSWEIdentifiable):
    def __init__(self, element):
        super(AbstractDataComponent, self).__init__(element)
        # Attributes
        self.definition     = testXMLAttribute(element,"definition")                        # anyURI, required
        self.updatable      = get_boolean(testXMLAttribute(element,"updatable"))            # boolean, optional
        self.optional       = get_boolean(testXMLAttribute(element,"optional")) or False    # boolean, default=False

class AbstractSimpleComponent(AbstractDataComponent):
    def __init__(self, element):
        super(AbstractSimpleComponent, self).__init__(element)
        # Attributes
        self.referenceFrame = testXMLAttribute(element,"referenceFrame")    # anyURI, optional
        self.axisID         = testXMLAttribute(element,"axisID")            # string, optional

        # Elements
        self.quality        = filter(None, [Quality(q) for q in [e.find('*') for e in element.findall(nspv("swe20:quality"))] if q is not None])
        try:
            self.nilValues  = NilValues(element.find(nspv("swe20:nilValues")))
        except:
            self.nilValues  = None

class Quality(object):
    def __new__(cls, element):
        t = element.tag.split("}")[-1]
        if t == "Quantity":
            return Quantity(element)
        elif t == "QuantityRange":
            return QuantityRange(element)
        elif t == "Category":
            return Category(element)
        elif t == "Text":
            return Text(element)
        else:
            return None

class NilValues(AbstractSWE):
    def __init__(self, element):
        super(NilValues, self).__init__(element)
        self.nilValue           = filter(None, [nilValue(x) for x in element.findall(nspv("swe20:nilValue"))]) # string, min=0, max=X

class nilValue(object):
    def __init__(self, element):
        self.reason             = testXMLAttribute(element, "reason")
        self.value              = testXMLValue(element)

class AllowedTokens(AbstractSWE):
    def __init__(self, element):
        super(AllowedTokens, self).__init__(element)
        self.value              = filter(None, [testXMLValue(x) for x in element.findall(nspv("swe20:value"))]) # string, min=0, max=X
        self.pattern            = testXMLValue(element.find(nspv("swe20:pattern")))                             # string (Unicode Technical Standard #18, Version 13), min=0

class AllowedValues(AbstractSWE):
    def __init__(self, element):
        super(AllowedValues, self).__init__(element)
        self.value              = filter(None, map(lambda x: get_float(x), [testXMLValue(x) for x in element.findall(nspv("swe20:value"))]))
        self.interval           = filter(None, [make_pair(testXMLValue(x)) for x in element.findall(nspv("swe20:interval"))])
        self.significantFigures = get_int(testXMLValue(element.find(nspv("swe20:significantFigures"))))                                         # integer, min=0

class AllowedTimes(AbstractSWE):
    def __init__(self, element):
        super(AllowedTimes, self).__init__(element)
        self.value              = filter(None, [testXMLValue(x) for x in element.findall(nspv("swe20:value"))])
        self.interval           = filter(None, [make_pair(testXMLValue(x)) for x in element.findall(nspv("swe20:interval"))])
        self.significantFigures = get_int(testXMLValue(element.find(nspv("swe20:significantFigures"))))                         # integer, min=0

class Boolean(AbstractSimpleComponent):
    def __init__(self, element):
        super(Boolean, self).__init__(element)
        # Elements
        """
        6.2.1 Boolean
                A Boolean representation of a proptery can take only two values that should be "true/false" or "yes/no".
        """
        value               = get_boolean(testXMLValue(element.find(nspv("swe20:value"))))   # boolean, min=0, max=1

class Text(AbstractSimpleComponent):
    def __init__(self, element):
        super(Text, self).__init__(element)
        # Elements
        """
        Req 6. A textual representation shall at least consist of a character string.
        """
        self.value          = testXMLValue(element.find(nspv("swe20:value")))                               # string, min=0, max=1

        try:
            self.constraint     = AllowedTokens(element.find(nspv("swe20:constraint/swe20:AllowedTokens"))) # AllowedTokens, min=0, max=1
        except:
            self.constraint     = None


class Category(AbstractSimpleComponent):
    def __init__(self, element):
        super(Category, self).__init__(element)
        # Elements
        self.codeSpace      = testXMLAttribute(element.find(nspv("swe20:codeSpace")), nspv("xlink:href"))   # Reference, min=0, max=1
        self.value          = testXMLValue(element.find(nspv("swe20:value")))                               # string, min=0, max=1

        try:
            self.constraint     = AllowedTokens(element.find(nspv("swe20:constraint/swe20:AllowedTokens"))) # AllowedTokens, min=0, max=1
        except:
            self.constraint     = None


class CategoryRange(Category):
    def __init__(self, element):
        super(CategoryRange, self).__init__(element)
        # Elements
        value               = testXMLValue(element.find(nspv("swe20:value")))
        self.values         = make_pair(value) if value is not None else None

class Count(AbstractSimpleComponent):
    def __init__(self, element):
        super(Count, self).__init__(element)
        # Elements
        self.value          = get_int(testXMLValue(element.find(nspv("swe20:value"))))                  # integer, min=0, max=1

        try:
            self.constraint = AllowedValues(element.find(nspv("swe20:constraint/swe20:AllowedValues"))) # AllowedValues, min=0, max=1
        except:
            self.constraint = None


class CountRange(Count):
    def __init__(self, element):
        super(CountRange, self).__init__(element)
        # Elements
        value               = testXMLValue(element.find(nspv("swe20:value")))
        self.value          = make_pair(value,int) if value is not None else None

class Quantity(AbstractSimpleComponent):
    def __init__(self, element):
        super(Quantity, self).__init__(element)
        # Elements
        self.uom            = get_uom(element.find(nspv("swe20:uom")))
        self.value          = get_float(testXMLValue(element.find(nspv("swe20:value"))))                  # double, min=0, max=1

        try:
            self.constraint = AllowedValues(element.find(nspv("swe20:constraint/swe20:AllowedValues")))   # AllowedValues, min=0, max=1
        except:
            self.constraint = None

class QuantityRange(Quantity):
    def __init__(self, element):
        super(QuantityRange, self).__init__(element)
        # Elements
        value               = testXMLValue(element.find(nspv("swe20:value")))
        self.value          = make_pair(value,float) if value is not None else None

def get_time(value, referenceTime, uom):
    try:
        value = parser.parse(value)

    except (AttributeError, ValueError): # Most likely an integer/float using a referenceTime
        try:
            if uom.lower() == "s":
                value  = referenceTime + timedelta(seconds=float(value))
            elif uom.lower() == "min":
                value  = referenceTime + timedelta(minutes=float(value))
            elif uom.lower() == "h":
                value  = referenceTime + timedelta(hours=float(value))
            elif uom.lower() == "d":
                value  = referenceTime + timedelta(days=float(value))

        except (AttributeError, ValueError):
            pass

    except OverflowError: # Too many numbers (> 10) or INF/-INF
        if value.lower() == "inf":
            value  = InfiniteDateTime()
        elif value.lower() == "-inf":
            value  = NegativeInfiniteDateTime()

    return value

class Time(AbstractSimpleComponent):
    def __init__(self, element):
        super(Time, self).__init__(element)
        # Elements
        self.uom                = get_uom(element.find(nspv("swe20:uom")))

        try:
            self.constraint     = AllowedTimes(element.find(nspv("swe20:constraint/swe20:AllowedTimes"))) # AllowedTimes, min=0, max=1
        except:
            self.constraint     = None

        # Attributes
        self.localFrame         = testXMLAttribute(element,"localFrame")                                    # anyURI, optional
        try:
            self.referenceTime  = parser.parse(testXMLAttribute(element,"referenceTime"))                   # dateTime, optional
        except (AttributeError, ValueError):
            self.referenceTime  = None

        value                   = testXMLValue(element.find(nspv("swe20:value")))                           # TimePosition, min=0, max=1
        self.value              = get_time(value, self.referenceTime, self.uom)

class TimeRange(AbstractSimpleComponent):
    def __init__(self, element):
        super(TimeRange, self).__init__(element)
        # Elements
        self.uom                = get_uom(element.find(nspv("swe20:uom")))

        try:
            self.constraint     = AllowedTimes(element.find(nspv("swe20:constraint/swe20:AllowedTimes"))) # AllowedTimes, min=0, max=1
        except:
            self.constraint     = None

        # Attributes
        self.localFrame         = testXMLAttribute(element,"localFrame")                                # anyURI, optional
        try:
            self.referenceTime  = parser.parse(testXMLAttribute(element,"referenceTime"))               # dateTime, optional
        except (AttributeError, ValueError):
            self.referenceTime  = None

        values                  = make_pair(testXMLValue(element.find(nspv("swe20:value"))))            # TimePosition, min=0, max=1
        self.value              = [get_time(t, self.referenceTime, self.uom) for t in values]

class DataRecord(AbstractDataComponent):
    def __init__(self, element):
        super(DataRecord, self).__init__(element)
        # Elements
        self.field          = [Field(x) for x in element.findall(nspv("swe20:field"))]
    def get_by_name(self, name):
        return next((x for x in self.field if x.name == name), None)

class Field(NamedObject):
    def __init__(self, element):
        super(Field, self).__init__(element)

class Vector(AbstractDataComponent):
    def __init__(self, element):
        super(Vector, self).__init__(element)
        # Elements
        self.coordinate     = [Coordinate(x) for x in element.findall(nspv("swe20:coordinate"))]

        # Attributes
        self.referenceFrame = testXMLAttribute(element,"referenceFrame")        # anyURI, required
        self.localFrame     = testXMLAttribute(element,"localFrame")            # anyURI, optional
    def get_by_name(self, name):
        return next((x for x in self.coordinate if x.name == name), None)

class Coordinate(NamedObject):
    def __init__(self, element):
        super(Coordinate, self).__init__(element)
        #if element[-1].tag not in AnyNumerical:
        #    print "Coordinate does not appear to be an AnyNumerical member"

class DataChoice(AbstractDataComponent):
    def __init__(self, element):
        super(DataChoice, self).__init__(element)
        self.item           = [Item(x) for x in element.findall(nspv("swe20:item"))]
    def get_by_name(self, name):
        return next((x for x in self.item if x.name == name), None)

class Item(NamedObject):
    def __init__(self, element):
        super(Item, self).__init__(element)

class DataArray(AbstractDataComponent):
    def __init__(self, element):
        super(DataArray, self).__init__(element)
        self.elementCount   = element.find(nspv("swe20:elementCount/swe20:Count"))      # required
        self.elementType    = ElementType(element.find(nspv("swe20:elementType")))      # required
        self.values         = testXMLValue(element.find(nspv("swe20:values")))
        try:
            self.encoding   = AbstractEncoding(element.find(nspv("swe20:encoding")))
        except:
            self.encoding   = None

class Matrix(AbstractDataComponent):
    def __init__(self, element):
        super(Matrix, self).__init__(element)
        self.elementCount   = element.find(nspv("swe20:elementCount/swe20:Count"))      # required
        self.elementType    = ElementType(element.find(nspv("swe20:elementType")))      # required
        self.encoding       = AbstractEncoding(element.find(nspv("swe20:encoding")))
        self.values         = testXMLValue(element.find(nspv("swe20:values")))
        self.referenceFrame = testXMLAttribute(element, "referenceFrame")               # anyURI, required
        self.localFrame     = testXMLAttribute(element, "localFrame")                   # anyURI, optional

class DataStream(AbstractSWEIdentifiable):
    def __init__(self, element):
        super(DataStream, self).__init__(element)
        self.elementCount   = element.find(nspv("swe20:elementCount/swe20:Count"))      # optional
        self.elementType    = ElementType(element.find(nspv("swe20:elementType")))      # optional
        self.encoding       = AbstractEncoding(element.find(nspv("swe20:encoding")))
        self.values         = testXMLValue(element.find(nspv("swe20:values")))

class ElementType(NamedObject):
    def __init__(self, element):
        super(ElementType, self).__init__(element)

class AbstractEncoding(object):
    def __new__(cls, element):
        t = element[-1].tag.split("}")[-1]
        if t == "TextEncoding":
            return super(AbstractEncoding, cls).__new__(TextEncoding, element)
        elif t == "XMLEncoding":
            return super(AbstractEncoding, cls).__new__(XMLEncoding, element)
        elif t == "BinaryEncoding":
            return super(AbstractEncoding, cls).__new__(BinaryEncoding, element)

class TextEncoding(AbstractEncoding):
    def __init__(self, element):
        self.tokenSeparator         = testXMLAttribute(element[-1], "tokenSeparator")                           # string,  required
        self.blockSeparator         = testXMLAttribute(element[-1], "blockSeparator")                           # string,  required
        self.decimalSeparator       = testXMLAttribute(element[-1], "decimalSeparator") or "."                  # string,  optional, default="."
        self.collapseWhiteSpaces    = get_boolean(testXMLAttribute(element[-1], "collapseWhiteSpaces")) or True # boolean, optional, default=True

class XMLEncoding(AbstractEncoding):
    def __init__(self, element):
        raise NotImplementedError

class BinaryEncoding(AbstractEncoding):
    def __init__(self, element):
        raise NotImplementedError

[((13, 9, 13, 21), 'owscapable.namespaces.Namespaces', 'Namespaces', ({}, {}), '()', False, 'from owscapable.namespaces import Namespaces\n'), ((18, 11, 18, 40), 'owscapable.util.nspath_eval', 'nspath_eval', ({(18, 23, 18, 27): 'path', (18, 29, 18, 39): 'namespaces'}, {}), '(path, namespaces)', False, 'from owscapable.util import nspath_eval\n'), ((36, 10, 36, 43), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(36, 27, 36, 34): 'element', (36, 36, 36, 42): '"""code"""'}, {}), "(element, 'code')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((70, 30, 70, 63), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(70, 47, 70, 54): 'element', (70, 56, 70, 62): '"""name"""'}, {}), "(element, 'name')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((85, 30, 85, 60), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(85, 47, 85, 54): 'element', (85, 55, 85, 59): '"""id"""'}, {}), "(element, 'id')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((102, 30, 102, 68), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(102, 47, 102, 54): 'element', (102, 55, 102, 67): '"""definition"""'}, {}), "(element, 'definition')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((110, 30, 110, 72), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(110, 47, 110, 54): 'element', (110, 55, 110, 71): '"""referenceFrame"""'}, {}), "(element, 'referenceFrame')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((111, 30, 111, 64), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(111, 47, 111, 54): 'element', (111, 55, 111, 63): '"""axisID"""'}, {}), "(element, 'axisID')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((141, 34, 141, 69), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(141, 51, 141, 58): 'element', (141, 60, 141, 68): '"""reason"""'}, {}), "(element, 'reason')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((142, 34, 142, 55), 'owscapable.util.testXMLValue', 'testXMLValue', ({(142, 47, 142, 54): 'element'}, {}), '(element)', False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((249, 16, 249, 35), 'dateutil.parser.parse', 'parser.parse', ({(249, 29, 249, 34): 'value'}, {}), '(value)', False, 'from dateutil import parser\n'), ((285, 34, 285, 72), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(285, 51, 285, 58): 'element', (285, 59, 285, 71): '"""localFrame"""'}, {}), "(element, 'localFrame')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((306, 34, 306, 72), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(306, 51, 306, 58): 'element', (306, 59, 306, 71): '"""localFrame"""'}, {}), "(element, 'localFrame')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((334, 30, 334, 72), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(334, 47, 334, 54): 'element', (334, 55, 334, 71): '"""referenceFrame"""'}, {}), "(element, 'referenceFrame')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((335, 30, 335, 68), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(335, 47, 335, 54): 'element', (335, 55, 335, 67): '"""localFrame"""'}, {}), "(element, 'localFrame')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((374, 30, 374, 73), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(374, 47, 374, 54): 'element', (374, 56, 374, 72): '"""referenceFrame"""'}, {}), "(element, 'referenceFrame')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((375, 30, 375, 69), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(375, 47, 375, 54): 'element', (375, 56, 375, 68): '"""localFrame"""'}, {}), "(element, 'localFrame')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((401, 38, 401, 85), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(401, 55, 401, 66): 'element[-1]', (401, 68, 401, 84): '"""tokenSeparator"""'}, {}), "(element[-1], 'tokenSeparator')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((402, 38, 402, 85), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(402, 55, 402, 66): 'element[-1]', (402, 68, 402, 84): '"""blockSeparator"""'}, {}), "(element[-1], 'blockSeparator')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((103, 42, 103, 79), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(103, 59, 103, 66): 'element', (103, 67, 103, 78): '"""updatable"""'}, {}), "(element, 'updatable')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((403, 38, 403, 87), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(403, 55, 403, 66): 'element[-1]', (403, 68, 403, 86): '"""decimalSeparator"""'}, {}), "(element[-1], 'decimalSeparator')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((104, 42, 104, 78), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(104, 59, 104, 66): 'element', (104, 67, 104, 77): '"""optional"""'}, {}), "(element, 'optional')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((147, 48, 147, 63), 'owscapable.util.testXMLValue', 'testXMLValue', ({(147, 61, 147, 62): 'x'}, {}), '(x)', False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((160, 48, 160, 63), 'owscapable.util.testXMLValue', 'testXMLValue', ({(160, 61, 160, 62): 'x'}, {}), '(x)', False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((267, 21, 267, 39), 'owscapable.util.InfiniteDateTime', 'InfiniteDateTime', ({}, {}), '()', False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((287, 47, 287, 88), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(287, 64, 287, 71): 'element', (287, 72, 287, 87): '"""referenceTime"""'}, {}), "(element, 'referenceTime')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((308, 47, 308, 88), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(308, 64, 308, 71): 'element', (308, 72, 308, 87): '"""referenceTime"""'}, {}), "(element, 'referenceTime')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((404, 50, 404, 102), 'owscapable.util.testXMLAttribute', 'testXMLAttribute', ({(404, 67, 404, 78): 'element[-1]', (404, 80, 404, 101): '"""collapseWhiteSpaces"""'}, {}), "(element[-1], 'collapseWhiteSpaces')", False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((153, 76, 153, 91), 'owscapable.util.testXMLValue', 'testXMLValue', ({(153, 89, 153, 90): 'x'}, {}), '(x)', False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((154, 58, 154, 73), 'owscapable.util.testXMLValue', 'testXMLValue', ({(154, 71, 154, 72): 'x'}, {}), '(x)', False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((161, 58, 161, 73), 'owscapable.util.testXMLValue', 'testXMLValue', ({(161, 71, 161, 72): 'x'}, {}), '(x)', False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n'), ((269, 21, 269, 47), 'owscapable.util.NegativeInfiniteDateTime', 'NegativeInfiniteDateTime', ({}, {}), '()', False, 'from owscapable.util import testXMLAttribute, testXMLValue, InfiniteDateTime, NegativeInfiniteDateTime\n')]