Send request to the aleph search engine.

    Request itself is pretty useless, but it can be later used as parameter
    for :func:`getDocumentIDs`, which can fetch records from Aleph.

    Args:
        base (str): which database you want to use
        phrase (str): what do you want to search
        considerSimilar (bool): fuzzy search, which is not working at all, so
                               don't use it
        field (str): where you want to look (see: :attr:`VALID_ALEPH_FIELDS`)

    Returns:
        dictionary: consisting from following fields:

            | error (optional): present if there was some form of error
            | no_entries (int): number of entries that can be fetch from aleph
            | no_records (int): no idea what is this, but it is always >= than
                                `no_entries`
            | set_number (int): important - something like ID of your request
            | session-id (str): used to count users for licensing purposes

    Example:
      Returned dict::

        {
         'session-id': 'YLI54HBQJESUTS678YYUNKEU4BNAUJDKA914GMF39J6K89VSCB',
         'set_number': 36520,
         'no_records': 1,
         'no_entries': 1
        }

    Raises:
        AlephException: if Aleph doesn't return any information
        InvalidAlephFieldException: if specified field is not valid

def searchInAleph(base, phrase, considerSimilar, field):
    """
    Send request to the aleph search engine.

    Request itself is pretty useless, but it can be later used as parameter
    for :func:`getDocumentIDs`, which can fetch records from Aleph.

    Args:
        base (str): which database you want to use
        phrase (str): what do you want to search
        considerSimilar (bool): fuzzy search, which is not working at all, so
                               don't use it
        field (str): where you want to look (see: :attr:`VALID_ALEPH_FIELDS`)

    Returns:
        dictionary: consisting from following fields:

            | error (optional): present if there was some form of error
            | no_entries (int): number of entries that can be fetch from aleph
            | no_records (int): no idea what is this, but it is always >= than
                                `no_entries`
            | set_number (int): important - something like ID of your request
            | session-id (str): used to count users for licensing purposes

    Example:
      Returned dict::

        {
         'session-id': 'YLI54HBQJESUTS678YYUNKEU4BNAUJDKA914GMF39J6K89VSCB',
         'set_number': 36520,
         'no_records': 1,
         'no_entries': 1
        }

    Raises:
        AlephException: if Aleph doesn't return any information
        InvalidAlephFieldException: if specified field is not valid
    """
    downer = Downloader()

    if field.lower() not in VALID_ALEPH_FIELDS:
        raise InvalidAlephFieldException("Unknown field '" + field + "'!")

    param_url = Template(SEARCH_URL_TEMPLATE).substitute(
        PHRASE=quote_plus(phrase),  # urlencode phrase
        BASE=base,
        FIELD=field,
        SIMILAR="Y" if considerSimilar else "N"
    )
    result = downer.download(ALEPH_URL + param_url)

    dom = dhtmlparser.parseString(result)

    find = dom.find("find")  # find <find> element :)
    if len(find) <= 0:
        raise AlephException("Aleph didn't returned any information.")
    find = find[0]

    # convert aleph result into dictionary
    result = _alephResultToDict(find)

    # add informations about base into result
    result["base"] = base

    if "error" not in result:
        return result

    # handle errors
    if result["error"] == "empty set":
        result["no_entries"] = 0  # empty set have 0 entries
        return result
    else:
        raise AlephException(result["error"])