docs: def dstk_parse(self, address, parser, pre_parsed_address=None):
          """
          Given an address string, use DSTK to parse the address and then coerce it to a normal Address object.
          pre_parsed_address for multi parsed string. Gives the value part for single dstk return value. If
          pre_parsed_address is None, parse it via dstk on its own.
          """
          if pre_parsed_address:
              dstk_address = pre_parsed_address
          else:
              if self.logger: self.logger.debug("Asking DSTK for address parse {0}".format(address.encode("ascii", "ignore")))
              dstk_address = parser.dstk.street2coordinates(address)
              # if self.logger: self.logger.debug("dstk return: {0}".format(dstk_address))
          if 'confidence' not in dstk_address:
              raise InvalidAddressException("Could not deal with DSTK return: {0}".format(dstk_address))
          if dstk_address['street_address'] == "":
              raise InvalidAddressException("Empty street address in DSTK return: {0}".format(dstk_address))
          if dstk_address['street_number']  is None or dstk_address['street_name'] is None:
              raise InvalidAddressException("House number or street name was Non in DSTK return: {0}".format(dstk_address))
          if dstk_address['confidence'] < parser.required_confidence:
              raise DSTKConfidenceTooLowException("Required confidence: {0}. Got confidence: {1}. Address: {2}. Return: {3}.".format(parser.required_confidence, dstk_address['confidence'], address.encode("ascii", "ignore"), dstk_address))
          self.confidence = dstk_address['confidence']
          if 'street_address' in dstk_address:
              intersections = self._get_dstk_intersections(address, dstk_address['street_address'])
          if self.logger: self.logger.debug("Confidence: {0}.".format(dstk_address['confidence']))
          if self.logger: self.logger.debug("Address: {0}.".format(address))
          if self.logger: self.logger.debug("Return: {0}.".format(dstk_address))
          # if self.logger: self.logger.debug("")
  
          addr = dstk_address
          if addr is None:
              raise InvalidAddressException("DSTK could not parse address: {0}".format(self.original))
          if "street_number" in addr:
              if addr["street_number"] not in address:
                  raise InvalidAddressException("DSTK returned a house number not in the original address: {0}".format(addr))
              self.house_number = addr["street_number"]
          else:
              raise InvalidAddressException("(dstk) Addresses must have house numbers: {0}".format(addr))
  
          if "locality" in addr:
              self.city = addr["locality"]
              # DSTK shouldn't be returning unknown cities
              if addr["locality"] not in address:
                  raise InvalidAddressException("DSTK returned a city not in the address. City: {0}, Address: {1}.".format(self.city, address))
          if "region" in addr:
              self.state = addr["region"]
              # if "fips_county" in addr:
              # self.zip = addr["fips_county"]
          if "latitude" in addr:
              self.lat = addr["latitude"]
          if "longitude" in addr:
              self.lng = addr["longitude"]
              # Try and find the apartment
          # First remove the street_address (this doesn't include apartment)
          if "street_address" in addr:
              apartment = address.replace(addr["street_address"], '')
          # Make sure the city doesn't somehow come before the street in the original string.
  
              # try:
              #     end_pos = re.search("(" + addr["locality"] + ")", apartment).start(1) - 1
              #     # self.apartment = apartment[:end_pos]
              # except Exception:
              #     pass
              # self.apartment = None
          # Now that we have an address, try to parse out street suffix, prefix, and street
          if self.apartment:
              street_addr = addr["street_address"].replace(self.apartment, '')
          else:
              street_addr = addr["street_address"]
  
          # We should be left with only prefix, street, suffix. Go for suffix first.
          split_addr = street_addr.split()
          if len(split_addr) == 0:
              if self.logger: self.logger.debug("Could not split street_address: {0}".format(addr))
              raise InvalidAddressException("Could not split street_address: {0}".format(addr))
          # Get rid of house_number
          if split_addr[0] == self.house_number:
              split_addr = split_addr[1:]
          if self.logger: self.logger.debug("Checking {0} for suffixes".format(split_addr[-1].upper()))
          if split_addr[-1].upper() in parser.suffixes.keys() or split_addr[-1].upper() in parser.suffixes.values():
              self.street_suffix = split_addr[-1]
              split_addr = split_addr[:-1]
          if self.logger: self.logger.debug("Checking {0} for prefixes".format(split_addr[0].lower()))
          if split_addr[0].lower() in parser.prefixes.keys() or split_addr[0].upper() in parser.prefixes.values() or \
                                  split_addr[0].upper() + '.' in parser.prefixes.values():
              if split_addr[0][-1] == '.':
                  self.street_prefix = split_addr[0].upper()
              else:
                  self.street_prefix = split_addr[0].upper() + '.'
              if self.logger: self.logger.debug("Saving prefix: {0}".format(self.street_prefix))
              split_addr = split_addr[1:]
          if self.logger: self.logger.debug("Saving street: {0}".format(split_addr))
          self.street = " ".join(split_addr)
          # DSTK shouldn't be guessing cities that come before streets.
          match = re.search(self.street, address)
          if match is None:
              raise InvalidAddressException("DSTK picked a street not in the original address. Street: {0}. Address: {1}.".format(self.street, address))
          street_position = match
          match = re.search(self.city, address)
          if match is None:
              raise InvalidAddressException("DSTK picked a city not in the original address. City: {0}. Address: {1}.".format(self.city, address))
          city_position = match
          if city_position.start(0) < street_position.end(0):
              raise InvalidAddressException("DSTK picked a street that comes after the city. Street: {0}. City: {1}. Address: {2}.".format(self.street, self.city, address))
          if self.logger: self.logger.debug("Successful DSTK address: {0}, house: {1}, street: {2}\n".format(self.original, self.house_number, self.street))