def build_ebay_item_model(single_item_response,
                          ebay_seller_id=None,
                          attempt_parse=False,
                          measurement_parse_strategy='default',
                          affiliate_url=None):
    """Takes an ebay_seller_id, and GetSingleItem ebay API response, and affiliate_url
	(if provided) and returns a appropriately configured Item model.

	Parameters
	----------
	single_item_response : dict
	ebay_seller_id : str
	attempt_parse : bool
		if true:
			- response will be searched for a description
			- will attempt to locate parser
			- parser will attempt to parse measurements and identify clothing type
	affiliate_url = str or None

	Returns
	-------
	configured sqlalchemy app.models.Item model object
		if attempt_parse=True and any part of the parsing process fails, will return None
	"""

    logger.debug('Attempting to create model')

    try:
        assert ebay_seller_id is not None
    except AssertionError:
        raise ValueError('ebay_seller_id not provided')
    try:
        seller = EbaySeller.query.filter(
            EbaySeller.ebay_seller_id == ebay_seller_id).one()
    except NoResultFound:
        # Couldn't find seller in database. Should fail.
        raise NoResultFound(
            'No matching seller found for <{}> in the database'.format(
                ebay_seller_id))

    logger.debug('Seller found. Using seller={}'.format(seller))

    # All times from these responses are UTC
    # http://developer.ebay.com/devzone/Shopping/docs/CallRef/types/simpleTypes.html#dateTime

    m = Item()
    m.last_access_date = datetime.strptime(single_item_response['Timestamp'],
                                           '%Y-%m-%dT%H:%M:%S.%fZ')

    r = single_item_response['Item']

    m.seller = seller
    m.ebay_item_id = int(r['ItemID'])
    m.end_date = datetime.strptime(r['EndTime'], '%Y-%m-%dT%H:%M:%S.%fZ')
    m.ebay_title = r['Title']
    m.primary_category_number = int(r['PrimaryCategoryID'])
    m.current_price = int(
        decimal.Decimal(r['ConvertedCurrentPrice']['value']) * 100)
    m.ebay_url = r['ViewItemURLForNaturalSearch']
    m.ebay_affiliate_url = affiliate_url

    if attempt_parse:
        # The thought process here is that with attempt_parse=True, it can be assumed that
        # for any item found, the measurements are also wanted. From that, if the
        # measurements cannot be created, the entire item should be discarded.

        # Thoughts: Maybe ParseResult should have an error attribute? This attribute should
        # a list of all errors encountered during parsing. Then, once ParseResult is
        # dehydrated, this list of errors is checked. If empty, proceed as normal. Else,
        # discard this item. This is better than assuming an invalid listing when no
        # measurements are returned. I can't think of scenarios where I want an item in the
        # database that without measurements, but... maybe I should keep those items anyways?

        logger.debug('Will attempt to parse')

        try:
            assert seller.template_parser is not None
        except AssertionError:
            logger.warn(
                'No template parser associated with <{}>. Returning None.'.
                format(seller))
            return None
            # raise ValueError(
            # 'No template parser associated with <{}>'.format(seller))

        try:
            # what error does this raise if it fails?
            parser_file_num = seller.template_parser.file_name_number
        except:
            raise

        logger.debug('A parser for this seller has been found')

        logger.debug('Passing off to master_parse')

        parse_input_json_str = json.dumps({
            'parser_id_num': parser_file_num,
            'parse_strategy': measurement_parse_strategy,
            'response': single_item_response
        })

        try:
            parser_response = master_parse.parse(parse_input_json_str)
        except Exception:
            logger.error('Something failed with the parser', exc_info=True)
            return None

        logger.debug('Attempting to rehydrate parse result')
        parse_result = ParseResult.rehydrate(parser_response)

        if parse_result.clothing_type is None:
            logger.warn(
                'Parser could not identify clothing type. Returning None')
            return None

        try:
            clothing_category = ClothingCategory.query.filter(
                ClothingCategory.clothing_category_name ==
                parse_result.clothing_type).one()
        except NoResultFound:
            logger.warn(
                'The parser returned a clothing category that could not be found '
                'by the database. Parser returned '
                'clothing_type={}. Returning None.'.format(
                    parse_result.clothing_type))
            return None

        m.assigned_clothing_category = clothing_category

        logger.debug(
            'Parser identified clothing category. Its db association is={}'.
            format(m.assigned_clothing_category))

        for concern in parse_result.meta['concerns']:
            logger.warn(
                'Parser returned this concern about what it was sent: {}'.
                format(concern))

        for msmt in parse_result.measurements:
            msmt_model = build_item_measurement(
                clothing_cat_string_name=msmt.category,
                attribute=msmt.attribute,
                measurement_value=msmt.value)
            m.measurements.append(msmt_model)

    logger.info('Model created successfully. Model={}'.format(m))

    return m