/*
 * Copyright 2006-2010 Jacek Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>
#include <assert.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "ole2.h"
#include "shlguid.h"
#include "wininet.h"
#include "shlwapi.h"

#include "wine/debug.h"

#include "mshtml_private.h"
#include "binding.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

#define NS_IOSERVICE_CLASSNAME "nsIOService"
#define NS_IOSERVICE_CONTRACTID "@mozilla.org/network/io-service;1"

static const IID NS_IOSERVICE_CID =
    {0x9ac9e770, 0x18bc, 0x11d3, {0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40}};
static const IID IID_nsWineURI =
    {0x5088272e, 0x900b, 0x11da, {0xc6,0x87, 0x00,0x0f,0xea,0x57,0xf2,0x1a}};

static nsIIOService *nsio = NULL;

static const char *request_method_strings[] = {"GET", "PUT", "POST"};

struct  nsWineURI {
    nsIFileURL nsIFileURL_iface; /* For non-file URL objects, it's just nsIURL */
    nsIStandardURL nsIStandardURL_iface;

    LONG ref;

    NSContainer *container;
    windowref_t *window_ref;
    nsChannelBSC *channel_bsc;
    IUri *uri;
    IUriBuilder *uri_builder;
    char *origin_charset;
    BOOL is_doc_uri;
    BOOL is_mutable;
    DWORD scheme;
};

static BOOL ensure_uri(nsWineURI *This)
{
    HRESULT hres;

    assert(This->uri || This->uri_builder);

    if(!This->uri) {
        hres = IUriBuilder_CreateUriSimple(This->uri_builder, 0, 0, &This->uri);
        if(FAILED(hres)) {
            WARN("CreateUriSimple failed: %08x\n", hres);
            return FALSE;
        }
    }

    return TRUE;
}

IUri *nsuri_get_uri(nsWineURI *nsuri)
{
    if(!ensure_uri(nsuri))
        return NULL;

    IUri_AddRef(nsuri->uri);
    return nsuri->uri;
}

IUri *get_uri_nofrag(IUri *uri)
{
    IUriBuilder *uri_builder;
    IUri *ret;
    BOOL b;
    HRESULT hres;

    hres = IUri_HasProperty(uri, Uri_PROPERTY_FRAGMENT, &b);
    if(SUCCEEDED(hres) && !b) {
        IUri_AddRef(uri);
        return uri;
    }

    hres = CreateIUriBuilder(uri, 0, 0, &uri_builder);
    if(FAILED(hres))
        return NULL;

    hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_FRAGMENT);
    if(SUCCEEDED(hres))
        hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &ret);
    IUriBuilder_Release(uri_builder);
    if(FAILED(hres))
        return NULL;

    return ret;
}

static BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2)
{
    IUri *uri_nofrag1, *uri_nofrag2;
    BOOL ret = FALSE;

    uri_nofrag1 = get_uri_nofrag(uri1);
    if(!uri_nofrag1)
        return FALSE;

    uri_nofrag2 = get_uri_nofrag(uri2);
    if(uri_nofrag2) {
        IUri_IsEqual(uri_nofrag1, uri_nofrag2, &ret);
        IUri_Release(uri_nofrag2);
    }

    IUri_Release(uri_nofrag1);
    return ret;
}

static HRESULT combine_url(IUri *base_uri, const WCHAR *rel_url, IUri **ret)
{
    IUri *uri_nofrag;
    HRESULT hres;

    uri_nofrag = get_uri_nofrag(base_uri);
    if(!uri_nofrag)
        return E_FAIL;

    hres = CoInternetCombineUrlEx(uri_nofrag, rel_url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
                ret, 0);
    IUri_Release(uri_nofrag);
    if(FAILED(hres))
        WARN("CoInternetCombineUrlEx failed: %08x\n", hres);
    return hres;
}

static nsresult create_nsuri(IUri*,HTMLOuterWindow*,NSContainer*,const char*,nsWineURI**);

static const char *debugstr_nsacstr(const nsACString *nsstr)
{
    const char *data;

    nsACString_GetData(nsstr, &data);
    return debugstr_a(data);
}

static nsresult return_wstr_nsacstr(nsACString *ret_str, const WCHAR *str, int len)
{
    char *stra;
    int lena;

    TRACE("returning %s\n", debugstr_wn(str, len));

    if(!*str) {
        nsACString_SetData(ret_str, "");
        return NS_OK;
    }

    lena = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
    stra = heap_alloc(lena+1);
    if(!stra)
        return NS_ERROR_OUT_OF_MEMORY;

    WideCharToMultiByte(CP_UTF8, 0, str, len, stra, lena, NULL, NULL);
    stra[lena] = 0;

    nsACString_SetData(ret_str, stra);
    heap_free(stra);
    return NS_OK;
}

HRESULT nsuri_to_url(LPCWSTR nsuri, BOOL ret_empty, BSTR *ret)
{
    const WCHAR *ptr = nsuri;

    static const WCHAR wine_prefixW[] = {'w','i','n','e',':'};

    if(!strncmpW(nsuri, wine_prefixW, sizeof(wine_prefixW)/sizeof(WCHAR)))
        ptr += sizeof(wine_prefixW)/sizeof(WCHAR);

    if(*ptr || ret_empty) {
        *ret = SysAllocString(ptr);
        if(!*ret)
            return E_OUTOFMEMORY;
    }else {
        *ret = NULL;
    }

    TRACE("%s -> %s\n", debugstr_w(nsuri), debugstr_w(*ret));
    return S_OK;
}

static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, BSTR url)
{
    IOleCommandTarget *cmdtrg = NULL;
    HRESULT hres;

    hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
    if(SUCCEEDED(hres)) {
        VARIANT varUrl, varRes;

        V_VT(&varUrl) = VT_BSTR;
        V_BSTR(&varUrl) = url;
        V_VT(&varRes) = VT_BOOL;

        hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 67, 0, &varUrl, &varRes);

        IOleCommandTarget_Release(cmdtrg);

        if(SUCCEEDED(hres) && !V_BOOL(&varRes)) {
            TRACE("got VARIANT_FALSE, do not load\n");
            return FALSE;
        }
    }

    return TRUE;
}

static nsresult before_async_open(nsChannel *channel, NSContainer *container, BOOL *cancel)
{
    HTMLDocumentObj *doc = container->doc;
    BSTR display_uri;
    HRESULT hres;

    if(!doc->client) {
        *cancel = TRUE;
        return NS_OK;
    }

    hres = IUri_GetDisplayUri(channel->uri->uri, &display_uri);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    if(!exec_shldocvw_67(doc, display_uri)) {
        SysFreeString(display_uri);
        *cancel = FALSE;
        return NS_OK;
    }

    hres = hlink_frame_navigate(&doc->basedoc, display_uri, channel, 0, cancel);
    SysFreeString(display_uri);
    if(FAILED(hres))
        *cancel = TRUE;
    return NS_OK;
}

HRESULT load_nsuri(HTMLOuterWindow *window, nsWineURI *uri, nsIInputStream *post_stream,
        nsChannelBSC *channelbsc, DWORD flags)
{
    nsIWebNavigation *web_navigation;
    nsIDocShellLoadInfo *load_info;
    nsIDocShell *doc_shell;
    HTMLDocumentNode *doc;
    nsresult nsres;

    nsres = get_nsinterface((nsISupports*)window->nswindow, &IID_nsIWebNavigation, (void**)&web_navigation);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIWebNavigation_QueryInterface(web_navigation, &IID_nsIDocShell, (void**)&doc_shell);
    nsIWebNavigation_Release(web_navigation);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIDocShell: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIDocShell_CreateLoadInfo(doc_shell, &load_info);
    if(NS_FAILED(nsres)) {
        nsIDocShell_Release(doc_shell);
        return E_FAIL;
    }

    nsres = nsIDocShellLoadInfo_SetLoadType(load_info, (flags & LOAD_FLAGS_BYPASS_CACHE) ? loadNormalBypassCache : loadNormal);
    assert(nsres == NS_OK);

    if(post_stream) {
        nsres = nsIDocShellLoadInfo_SetPostDataStream(load_info, post_stream);
        assert(nsres == NS_OK);
    }

    if(window->uri_nofrag) {
        nsWineURI *referrer_uri;
        nsres = create_nsuri(window->uri_nofrag, window, window->doc_obj ? window->doc_obj->nscontainer : NULL,  NULL, &referrer_uri);
        if(NS_SUCCEEDED(nsres)) {
            nsres = nsIDocShellLoadInfo_SetReferrer(load_info, (nsIURI*)&referrer_uri->nsIFileURL_iface);
            assert(nsres == NS_OK);
            nsIFileURL_Release(&referrer_uri->nsIFileURL_iface);
        }
    }

    uri->channel_bsc = channelbsc;
    doc = window->base.inner_window->doc;
    doc->skip_mutation_notif = TRUE;
    nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIFileURL_iface, load_info, flags, FALSE);
    if(doc == window->base.inner_window->doc)
        doc->skip_mutation_notif = FALSE;
    uri->channel_bsc = NULL;
    nsIDocShell_Release(doc_shell);
    nsIDocShellLoadInfo_Release(load_info);
    if(NS_FAILED(nsres)) {
        WARN("LoadURI failed: %08x\n", nsres);
        return E_FAIL;
    }

    return S_OK;
}

static void set_uri_nscontainer(nsWineURI *This, NSContainer *nscontainer)
{
    if(This->container) {
        if(This->container == nscontainer)
            return;
        TRACE("Changing %p -> %p\n", This->container, nscontainer);
        nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
    }

    if(nscontainer)
        nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
    This->container = nscontainer;
}

static void set_uri_window(nsWineURI *This, HTMLOuterWindow *window)
{
    if(This->window_ref) {
        if(This->window_ref->window == window)
            return;
        TRACE("Changing %p -> %p\n", This->window_ref->window, window);
        windowref_release(This->window_ref);
    }

    if(window) {
        windowref_addref(window->window_ref);
        This->window_ref = window->window_ref;

        if(window->doc_obj)
            set_uri_nscontainer(This, window->doc_obj->nscontainer);
    }else {
        This->window_ref = NULL;
    }
}

static inline BOOL is_http_channel(nsChannel *This)
{
    return This->uri->scheme == URL_SCHEME_HTTP || This->uri->scheme == URL_SCHEME_HTTPS;
}

static http_header_t *find_http_header(struct list *headers, const WCHAR *name, int len)
{
    http_header_t *iter;

    LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
        if(!strncmpiW(iter->header, name, len) && !iter->header[len])
            return iter;
    }

    return NULL;
}

static nsresult get_channel_http_header(struct list *headers, const nsACString *header_name_str,
        nsACString *_retval)
{
    const char *header_namea;
    http_header_t *header;
    WCHAR *header_name;
    char *data;

    nsACString_GetData(header_name_str, &header_namea);
    header_name = heap_strdupAtoW(header_namea);
    if(!header_name)
        return NS_ERROR_UNEXPECTED;

    header = find_http_header(headers, header_name, strlenW(header_name));
    heap_free(header_name);
    if(!header)
        return NS_ERROR_NOT_AVAILABLE;

    data = heap_strdupWtoA(header->data);
    if(!data)
        return NS_ERROR_UNEXPECTED;

    TRACE("%s -> %s\n", debugstr_a(header_namea), debugstr_a(data));
    nsACString_SetData(_retval, data);
    heap_free(data);
    return NS_OK;
}

HRESULT set_http_header(struct list *headers, const WCHAR *name, int name_len,
        const WCHAR *value, int value_len)
{
    http_header_t *header;

    TRACE("%s: %s\n", debugstr_wn(name, name_len), debugstr_wn(value, value_len));

    header = find_http_header(headers, name, name_len);
    if(header) {
        WCHAR *new_data;

        new_data = heap_strndupW(value, value_len);
        if(!new_data)
            return E_OUTOFMEMORY;

        heap_free(header->data);
        header->data = new_data;
    }else {
        header = heap_alloc(sizeof(http_header_t));
        if(!header)
            return E_OUTOFMEMORY;

        header->header = heap_strndupW(name, name_len);
        header->data = heap_strndupW(value, value_len);
        if(!header->header || !header->data) {
            heap_free(header->header);
            heap_free(header->data);
            heap_free(header);
            return E_OUTOFMEMORY;
        }

        list_add_tail(headers, &header->entry);
    }

    return S_OK;
}

static nsresult set_channel_http_header(struct list *headers, const nsACString *name_str,
        const nsACString *value_str)
{
    const char *namea, *valuea;
    WCHAR *name, *value;
    HRESULT hres;

    nsACString_GetData(name_str, &namea);
    name = heap_strdupAtoW(namea);
    if(!name)
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(value_str, &valuea);
    value = heap_strdupAtoW(valuea);
    if(!value) {
        heap_free(name);
        return NS_ERROR_UNEXPECTED;
    }

    hres = set_http_header(headers, name, strlenW(name), value, strlenW(value));

    heap_free(name);
    heap_free(value);
    return SUCCEEDED(hres) ? NS_OK : NS_ERROR_UNEXPECTED;
}

static nsresult visit_http_headers(struct list *headers, nsIHttpHeaderVisitor *visitor)
{
    nsACString header_str, value_str;
    char *header, *value;
    http_header_t *iter;
    nsresult nsres;

    LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
        header = heap_strdupWtoA(iter->header);
        if(!header)
            return NS_ERROR_OUT_OF_MEMORY;

        value = heap_strdupWtoA(iter->data);
        if(!value) {
            heap_free(header);
            return NS_ERROR_OUT_OF_MEMORY;
        }

        nsACString_InitDepend(&header_str, header);
        nsACString_InitDepend(&value_str, value);
        nsres = nsIHttpHeaderVisitor_VisitHeader(visitor, &header_str, &value_str);
        nsACString_Finish(&header_str);
        nsACString_Finish(&value_str);
        heap_free(header);
        heap_free(value);
        if(NS_FAILED(nsres))
            break;
    }

    return NS_OK;
}

static void free_http_headers(struct list *list)
{
    http_header_t *iter, *iter_next;

    LIST_FOR_EACH_ENTRY_SAFE(iter, iter_next, list, http_header_t, entry) {
        list_remove(&iter->entry);
        heap_free(iter->header);
        heap_free(iter->data);
        heap_free(iter);
    }
}

static inline nsChannel *impl_from_nsIHttpChannel(nsIHttpChannel *iface)
{
    return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannel_iface);
}

static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef riid, void **result)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    if(IsEqualGUID(&IID_nsISupports, riid)) {
        TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
        *result = &This->nsIHttpChannel_iface;
    }else if(IsEqualGUID(&IID_nsIRequest, riid)) {
        TRACE("(%p)->(IID_nsIRequest %p)\n", This, result);
        *result = &This->nsIHttpChannel_iface;
    }else if(IsEqualGUID(&IID_nsIChannel, riid)) {
        TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
        *result = &This->nsIHttpChannel_iface;
    }else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
        TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
        *result = is_http_channel(This) ? &This->nsIHttpChannel_iface : NULL;
    }else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
        TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
        *result = &This->nsIUploadChannel_iface;
    }else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
        TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
        *result = is_http_channel(This) ? &This->nsIHttpChannelInternal_iface : NULL;
    }else {
        TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
        *result = NULL;
    }

    if(*result) {
        nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
        return NS_OK;
    }

    return NS_NOINTERFACE;
}

static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    nsrefcnt ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    if(!ref) {
        nsIFileURL_Release(&This->uri->nsIFileURL_iface);
        if(This->owner)
            nsISupports_Release(This->owner);
        if(This->post_data_stream)
            nsIInputStream_Release(This->post_data_stream);
        if(This->load_group)
            nsILoadGroup_Release(This->load_group);
        if(This->notif_callback)
            nsIInterfaceRequestor_Release(This->notif_callback);
        if(This->original_uri)
            nsIURI_Release(This->original_uri);
        if(This->referrer)
            nsIURI_Release(This->referrer);

        free_http_headers(&This->response_headers);
        free_http_headers(&This->request_headers);

        heap_free(This->content_type);
        heap_free(This->charset);
        heap_free(This);
    }

    return ref;
}

static nsresult NSAPI nsChannel_GetName(nsIHttpChannel *iface, nsACString *aName)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aName);

    return nsIFileURL_GetSpec(&This->uri->nsIFileURL_iface, aName);
}

static nsresult NSAPI nsChannel_IsPending(nsIHttpChannel *iface, cpp_bool *_retval)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, _retval);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStatus)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    WARN("(%p)->(%p) returning NS_OK\n", This, aStatus);

    return *aStatus = NS_OK;
}

static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%08x)\n", This, aStatus);

    if(This->binding && This->binding->bsc.binding)
        IBinding_Abort(This->binding->bsc.binding);
    else
        WARN("No binding to cancel\n");
    return NS_OK;
}

static nsresult NSAPI nsChannel_Suspend(nsIHttpChannel *iface)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_Resume(nsIHttpChannel *iface)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetLoadGroup(nsIHttpChannel *iface, nsILoadGroup **aLoadGroup)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aLoadGroup);

    if(This->load_group)
        nsILoadGroup_AddRef(This->load_group);

    *aLoadGroup = This->load_group;
    return NS_OK;
}

static nsresult NSAPI nsChannel_SetLoadGroup(nsIHttpChannel *iface, nsILoadGroup *aLoadGroup)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aLoadGroup);

    if(This->load_group)
        nsILoadGroup_Release(This->load_group);
    if(aLoadGroup)
        nsILoadGroup_AddRef(aLoadGroup);
    This->load_group = aLoadGroup;

    return NS_OK;
}

static nsresult NSAPI nsChannel_GetLoadFlags(nsIHttpChannel *iface, nsLoadFlags *aLoadFlags)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aLoadFlags);

    *aLoadFlags = This->load_flags;
    return NS_OK;
}

static nsresult NSAPI nsChannel_SetLoadFlags(nsIHttpChannel *iface, nsLoadFlags aLoadFlags)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%08x)\n", This, aLoadFlags);

    This->load_flags = aLoadFlags;
    return NS_OK;
}

static nsresult NSAPI nsChannel_GetOriginalURI(nsIHttpChannel *iface, nsIURI **aOriginalURI)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aOriginalURI);

    if(This->original_uri)
        nsIURI_AddRef(This->original_uri);

    *aOriginalURI = This->original_uri;
    return NS_OK;
}

static nsresult NSAPI nsChannel_SetOriginalURI(nsIHttpChannel *iface, nsIURI *aOriginalURI)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aOriginalURI);

    if(This->original_uri)
        nsIURI_Release(This->original_uri);

    nsIURI_AddRef(aOriginalURI);
    This->original_uri = aOriginalURI;
    return NS_OK;
}

static nsresult NSAPI nsChannel_GetURI(nsIHttpChannel *iface, nsIURI **aURI)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aURI);

    nsIFileURL_AddRef(&This->uri->nsIFileURL_iface);
    *aURI = (nsIURI*)&This->uri->nsIFileURL_iface;

    return NS_OK;
}

static nsresult NSAPI nsChannel_GetOwner(nsIHttpChannel *iface, nsISupports **aOwner)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aOwner);

    if(This->owner)
        nsISupports_AddRef(This->owner);
    *aOwner = This->owner;

    return NS_OK;
}

static nsresult NSAPI nsChannel_SetOwner(nsIHttpChannel *iface, nsISupports *aOwner)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aOwner);

    if(aOwner)
        nsISupports_AddRef(aOwner);
    if(This->owner)
        nsISupports_Release(This->owner);
    This->owner = aOwner;

    return NS_OK;
}

static nsresult NSAPI nsChannel_GetNotificationCallbacks(nsIHttpChannel *iface,
        nsIInterfaceRequestor **aNotificationCallbacks)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);

    if(This->notif_callback)
        nsIInterfaceRequestor_AddRef(This->notif_callback);
    *aNotificationCallbacks = This->notif_callback;

    return NS_OK;
}

static nsresult NSAPI nsChannel_SetNotificationCallbacks(nsIHttpChannel *iface,
        nsIInterfaceRequestor *aNotificationCallbacks)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);

    if(This->notif_callback)
        nsIInterfaceRequestor_Release(This->notif_callback);
    if(aNotificationCallbacks)
        nsIInterfaceRequestor_AddRef(aNotificationCallbacks);

    This->notif_callback = aNotificationCallbacks;

    return NS_OK;
}

static nsresult NSAPI nsChannel_GetSecurityInfo(nsIHttpChannel *iface, nsISupports **aSecurityInfo)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aSecurityInfo);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString *aContentType)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aContentType);

    if(This->content_type) {
        nsACString_SetData(aContentType, This->content_type);
        return S_OK;
    }

    if(This->uri->is_doc_uri) {
        WARN("Document channel with no MIME set. Assuming text/html\n");
        nsACString_SetData(aContentType, "text/html");
        return S_OK;
    }

    WARN("unknown type\n");
    return NS_ERROR_FAILURE;
}

static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
                                               const nsACString *aContentType)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    const char *content_type;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentType));

    nsACString_GetData(aContentType, &content_type);
    heap_free(This->content_type);
    This->content_type = heap_strdupA(content_type);

    return NS_OK;
}

static nsresult NSAPI nsChannel_GetContentCharset(nsIHttpChannel *iface,
                                                  nsACString *aContentCharset)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aContentCharset);

    if(This->charset) {
        nsACString_SetData(aContentCharset, This->charset);
        return NS_OK;
    }

    nsACString_SetData(aContentCharset, "");
    return NS_OK;
}

static nsresult NSAPI nsChannel_SetContentCharset(nsIHttpChannel *iface,
                                                  const nsACString *aContentCharset)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    const char *data;
    char *charset;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentCharset));

    nsACString_GetData(aContentCharset, &data);
    charset = heap_strdupA(data);
    if(!charset)
        return NS_ERROR_OUT_OF_MEMORY;

    heap_free(This->charset);
    This->charset = charset;
    return NS_OK;
}

static nsresult NSAPI nsChannel_GetContentLength(nsIHttpChannel *iface, INT64 *aContentLength)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, aContentLength);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_SetContentLength(nsIHttpChannel *iface, INT64 aContentLength)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aContentLength));

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_retval)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, _retval);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_Open2(nsIHttpChannel *iface, nsIInputStream **_retval)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, _retval);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static HTMLOuterWindow *get_window_from_load_group(nsChannel *This)
{
    HTMLOuterWindow *window;
    nsIChannel *channel;
    nsIRequest *req;
    nsWineURI *wine_uri;
    nsIURI *uri;
    nsresult nsres;

    nsres = nsILoadGroup_GetDefaultLoadRequest(This->load_group, &req);
    if(NS_FAILED(nsres)) {
        ERR("GetDefaultLoadRequest failed: %08x\n", nsres);
        return NULL;
    }

    if(!req)
        return NULL;

    nsres = nsIRequest_QueryInterface(req, &IID_nsIChannel, (void**)&channel);
    nsIRequest_Release(req);
    if(NS_FAILED(nsres)) {
        WARN("Could not get nsIChannel interface: %08x\n", nsres);
        return NULL;
    }

    nsres = nsIChannel_GetURI(channel, &uri);
    nsIChannel_Release(channel);
    if(NS_FAILED(nsres)) {
        ERR("GetURI failed: %08x\n", nsres);
        return NULL;
    }

    nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
    nsIURI_Release(uri);
    if(NS_FAILED(nsres)) {
        TRACE("Could not get nsWineURI: %08x\n", nsres);
        return NULL;
    }

    window = wine_uri->window_ref ? wine_uri->window_ref->window : NULL;
    if(window)
        IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
    nsIFileURL_Release(&wine_uri->nsIFileURL_iface);

    return window;
}

static HTMLOuterWindow *get_channel_window(nsChannel *This)
{
    nsIWebProgress *web_progress;
    mozIDOMWindowProxy *mozwindow;
    HTMLOuterWindow *window;
    nsresult nsres;

    if(This->load_group) {
        nsIRequestObserver *req_observer;

        nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
        if(NS_FAILED(nsres) || !req_observer) {
            ERR("GetGroupObserver failed: %08x\n", nsres);
            return NULL;
        }

        nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
        nsIRequestObserver_Release(req_observer);
        if(NS_FAILED(nsres)) {
            ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
            return NULL;
        }
    }else if(This->notif_callback) {
        nsres = nsIInterfaceRequestor_GetInterface(This->notif_callback, &IID_nsIWebProgress, (void**)&web_progress);
        if(NS_FAILED(nsres)) {
            ERR("GetInterface(IID_nsIWebProgress failed: %08x\n", nsres);
            return NULL;
        }
    }else {
        ERR("no load group nor notif callback\n");
        return NULL;
    }

    nsres = nsIWebProgress_GetDOMWindow(web_progress, &mozwindow);
    nsIWebProgress_Release(web_progress);
    if(NS_FAILED(nsres) || !mozwindow) {
        ERR("GetDOMWindow failed: %08x\n", nsres);
        return NULL;
    }

    window = mozwindow_to_window(mozwindow);
    mozIDOMWindowProxy_Release(mozwindow);

    if(window)
        IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
    else
        FIXME("NULL window for %p\n", mozwindow);
    return window;
}

typedef struct {
    task_t header;
    HTMLInnerWindow *window;
    nsChannelBSC *bscallback;
} start_binding_task_t;

static void start_binding_proc(task_t *_task)
{
    start_binding_task_t *task = (start_binding_task_t*)_task;

    start_binding(task->window, (BSCallback*)task->bscallback, NULL);
}

static void start_binding_task_destr(task_t *_task)
{
    start_binding_task_t *task = (start_binding_task_t*)_task;

    IBindStatusCallback_Release(&task->bscallback->bsc.IBindStatusCallback_iface);
    heap_free(task);
}

static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
        nsISupports *context)
{
    nsChannelBSC *bscallback;
    IMoniker *mon = NULL;
    HRESULT hres;

    hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0);
    if(FAILED(hres)) {
        WARN("CreateURLMoniker failed: %08x\n", hres);
        return NS_ERROR_UNEXPECTED;
    }

    if(is_doc_channel)
        set_current_mon(window, mon, BINDING_NAVIGATED);

    hres = create_channelbsc(mon, NULL, NULL, 0, is_doc_channel, &bscallback);
    IMoniker_Release(mon);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    channelbsc_set_channel(bscallback, This, listener, context);

    if(is_doc_channel) {
        hres = create_pending_window(window, bscallback);
        if(SUCCEEDED(hres))
            async_start_doc_binding(window, window->pending_window);
        IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
        if(FAILED(hres))
            return NS_ERROR_UNEXPECTED;
    }else {
        start_binding_task_t *task;

        task = heap_alloc(sizeof(start_binding_task_t));
        if(!task) {
            IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
            return NS_ERROR_OUT_OF_MEMORY;
        }

        task->window = window->base.inner_window;
        task->bscallback = bscallback;
        hres = push_task(&task->header, start_binding_proc, start_binding_task_destr, window->base.inner_window->task_magic);
        if(FAILED(hres))
            return NS_ERROR_OUT_OF_MEMORY;
    }

    return NS_OK;
}

static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListener *aListener,
                                          nsISupports *aContext)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    HTMLOuterWindow *window = NULL;
    BOOL cancel = FALSE;
    nsresult nsres = NS_OK;

    TRACE("(%p)->(%p %p)\n", This, aListener, aContext);

    if(!ensure_uri(This->uri))
        return NS_ERROR_FAILURE;

    if(TRACE_ON(mshtml)) {
        HRESULT hres;
        BSTR uri_str;

        hres = IUri_GetDisplayUri(This->uri->uri, &uri_str);
        if(SUCCEEDED(hres)) {
            TRACE("opening %s\n", debugstr_w(uri_str));
            SysFreeString(uri_str);
        }else {
            WARN("GetDisplayUri failed: %08x\n", hres);
        }
    }

    if(This->uri->is_doc_uri) {
        window = get_channel_window(This);
        if(window) {
            set_uri_window(This->uri, window);
        }else if(This->uri->container) {
            BOOL b;

            /* nscontainer->doc should be NULL which means navigation to a new window */
            if(This->uri->container->doc)
                FIXME("nscontainer->doc = %p\n", This->uri->container->doc);

            nsres = before_async_open(This, This->uri->container, &b);
            if(NS_FAILED(nsres))
                return nsres;
            if(b)
                FIXME("Navigation not cancelled\n");
            return NS_ERROR_UNEXPECTED;
        }
    }

    if(!window) {
        if(This->uri->window_ref && This->uri->window_ref->window) {
            window = This->uri->window_ref->window;
            IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
        }else {
            /* FIXME: Analyze removing get_window_from_load_group call */
            if(This->load_group)
                window = get_window_from_load_group(This);
            if(!window)
                window = get_channel_window(This);
            if(window)
                set_uri_window(This->uri, window);
        }
    }

    if(!window) {
        ERR("window = NULL\n");
        return NS_ERROR_UNEXPECTED;
    }

    if(This->uri->is_doc_uri && window == window->doc_obj->basedoc.window) {
        if(This->uri->channel_bsc) {
            channelbsc_set_channel(This->uri->channel_bsc, This, aListener, aContext);

            if(window->doc_obj->mime) {
                heap_free(This->content_type);
                This->content_type = heap_strdupWtoA(window->doc_obj->mime);
            }

            cancel = TRUE;
        }else {
            nsres = before_async_open(This, window->doc_obj->nscontainer, &cancel);
            if(NS_SUCCEEDED(nsres)  && cancel) {
                TRACE("canceled\n");
                nsres = NS_BINDING_ABORTED;
            }
        }
    }

    if(!cancel)
        nsres = async_open(This, window, This->uri->is_doc_uri, aListener, aContext);

    if(NS_SUCCEEDED(nsres) && This->load_group) {
        nsres = nsILoadGroup_AddRequest(This->load_group, (nsIRequest*)&This->nsIHttpChannel_iface,
                aContext);
        if(NS_FAILED(nsres))
            ERR("AddRequest failed: %08x\n", nsres);
    }

    IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
    return nsres;
}

static nsresult NSAPI nsChannel_AsyncOpen2(nsIHttpChannel *iface, nsIStreamListener *aListener)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aListener);
    return nsIHttpChannel_AsyncOpen(&This->nsIHttpChannel_iface, aListener, NULL);
}

static nsresult NSAPI nsChannel_GetContentDisposition(nsIHttpChannel *iface, UINT32 *aContentDisposition)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aContentDisposition);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_SetContentDisposition(nsIHttpChannel *iface, UINT32 aContentDisposition)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%u)\n", This, aContentDisposition);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetContentDispositionFilename(nsIHttpChannel *iface, nsAString *aContentDispositionFilename)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_SetContentDispositionFilename(nsIHttpChannel *iface, const nsAString *aContentDispositionFilename)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetContentDispositionHeader(nsIHttpChannel *iface, nsACString *aContentDispositionHeader)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aContentDispositionHeader);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetLoadInfo(nsIHttpChannel *iface, nsILoadInfo **aLoadInfo)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aLoadInfo);

    if(This->load_info)
        nsISupports_AddRef(This->load_info);
    *aLoadInfo = This->load_info;
    return NS_OK;
}

static nsresult NSAPI nsChannel_SetLoadInfo(nsIHttpChannel *iface, nsILoadInfo *aLoadInfo)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aLoadInfo);

    if(This->load_info)
        nsISupports_Release(This->load_info);
    This->load_info = aLoadInfo;
    if(This->load_info)
        nsISupports_AddRef(This->load_info);
    return NS_OK;
}

static nsresult NSAPI nsChannel_GetRequestMethod(nsIHttpChannel *iface, nsACString *aRequestMethod)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aRequestMethod);

    nsACString_SetData(aRequestMethod, request_method_strings[This->request_method]);
    return NS_OK;
}

static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
                                                 const nsACString *aRequestMethod)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    const char *method;
    unsigned i;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRequestMethod));

    nsACString_GetData(aRequestMethod, &method);
    for(i=0; i < sizeof(request_method_strings)/sizeof(*request_method_strings); i++) {
        if(!strcasecmp(method, request_method_strings[i])) {
            This->request_method = i;
            return NS_OK;
        }
    }

    ERR("Invalid method %s\n", debugstr_a(method));
    return NS_ERROR_UNEXPECTED;
}

static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aReferrer);

    if(This->referrer)
        nsIURI_AddRef(This->referrer);
    *aReferrer = This->referrer;
    return NS_OK;
}

static nsresult NSAPI nsChannel_SetReferrer(nsIHttpChannel *iface, nsIURI *aReferrer)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aReferrer);

    return nsIHttpChannel_SetReferrerWithPolicy(&This->nsIHttpChannel_iface, aReferrer, 0);
}

static nsresult NSAPI nsChannel_GetReferrerPolicy(nsIHttpChannel *iface, UINT32 *aReferrerPolicy)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aReferrerPolicy);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_SetReferrerWithPolicy(nsIHttpChannel *iface, nsIURI *aReferrer, UINT32 aReferrerPolicy)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    DWORD channel_scheme, referrer_scheme;
    nsWineURI *referrer;
    BSTR referrer_uri;
    nsresult nsres;
    HRESULT hres;

    static const WCHAR refererW[] = {'R','e','f','e','r','e','r'};

    TRACE("(%p)->(%p %d)\n", This, aReferrer, aReferrerPolicy);

    if(aReferrerPolicy)
        FIXME("refferer policy %d not implemented\n", aReferrerPolicy);

    if(This->referrer) {
        nsIURI_Release(This->referrer);
        This->referrer = NULL;
    }
    if(!aReferrer)
        return NS_OK;

    nsres = nsIURI_QueryInterface(aReferrer, &IID_nsWineURI, (void**)&referrer);
    if(NS_FAILED(nsres))
        return NS_OK;

    if(!ensure_uri(referrer)) {
        nsIFileURL_Release(&referrer->nsIFileURL_iface);
        return NS_ERROR_UNEXPECTED;
    }

    if(!ensure_uri(This->uri) || FAILED(IUri_GetScheme(This->uri->uri, &channel_scheme)))
        channel_scheme = INTERNET_SCHEME_UNKNOWN;

    if(FAILED(IUri_GetScheme(referrer->uri, &referrer_scheme)))
        referrer_scheme = INTERNET_SCHEME_UNKNOWN;

    if(referrer_scheme == INTERNET_SCHEME_HTTPS && channel_scheme != INTERNET_SCHEME_HTTPS) {
        TRACE("Ignoring https referrer on non-https channel\n");
        nsIFileURL_Release(&referrer->nsIFileURL_iface);
        return NS_OK;
    }

    hres = IUri_GetDisplayUri(referrer->uri, &referrer_uri);
    if(SUCCEEDED(hres)) {
        set_http_header(&This->request_headers, refererW, sizeof(refererW)/sizeof(WCHAR), referrer_uri, SysStringLen(referrer_uri));
        SysFreeString(referrer_uri);
    }

    This->referrer = (nsIURI*)&referrer->nsIFileURL_iface;
    return NS_OK;
}

static nsresult NSAPI nsHttpChannel_GetProtocolVersion(nsIHttpChannel *iface, nsACString *aProtocolVersion)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aProtocolVersion);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannel_GetTransferSize(nsIHttpChannel *iface, UINT64 *aTransferSize)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aTransferSize);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannel_GetDecodedBodySize(nsIHttpChannel *iface, UINT64 *aDecodedBodySize)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aDecodedBodySize);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannel_GetEncodedBodySize(nsIHttpChannel *iface, UINT64 *aEncodedBodySize)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aEncodedBodySize);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
         const nsACString *aHeader, nsACString *_retval)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aHeader), _retval);

    return get_channel_http_header(&This->request_headers, aHeader, _retval);
}

static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
         const nsACString *aHeader, const nsACString *aValue, cpp_bool aMerge)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(aHeader), debugstr_nsacstr(aValue), aMerge);

    if(aMerge)
        FIXME("aMerge not supported\n");

    return set_channel_http_header(&This->request_headers, aHeader, aValue);
}

static nsresult NSAPI nsChannel_SetEmptyRequestHeader(nsIHttpChannel *iface, const nsACString *aHeader)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aHeader));
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
                                                    nsIHttpHeaderVisitor *aVisitor)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, aVisitor);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_VisitNonDefaultRequestHeaders(nsIHttpChannel *iface, nsIHttpHeaderVisitor *aVisitor)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aVisitor);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, cpp_bool *aAllowPipelining)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, aAllowPipelining);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, cpp_bool aAllowPipelining)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%x)\n", This, aAllowPipelining);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetAllowTLS(nsIHttpChannel *iface, cpp_bool *aAllowTLS)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aAllowTLS);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_SetAllowTLS(nsIHttpChannel *iface, cpp_bool aAllowTLS)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%x)\n", This, aAllowTLS);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, UINT32 *aRedirectionLimit)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, aRedirectionLimit);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, UINT32 aRedirectionLimit)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%u)\n", This, aRedirectionLimit);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, UINT32 *aResponseStatus)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aResponseStatus);

    if(This->response_status) {
        *aResponseStatus = This->response_status;
        return NS_OK;
    }

    WARN("No response status\n");
    return NS_ERROR_UNEXPECTED;
}

static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
                                                      nsACString *aResponseStatusText)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aResponseStatusText);

    nsACString_SetData(aResponseStatusText, This->response_status_text);
    return NS_OK;
}

static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
                                                    cpp_bool *aRequestSucceeded)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aRequestSucceeded);

    if(!This->response_status)
        return NS_ERROR_NOT_AVAILABLE;

    *aRequestSucceeded = This->response_status/100 == 2;

    return NS_OK;
}

static nsresult NSAPI nsChannel_GetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool *aIsMainDocumentChannel)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%p)\n", This, aIsMainDocumentChannel);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_SetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool aIsMainDocumentChannel)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    FIXME("(%p)->(%x)\n", This, aIsMainDocumentChannel);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
         const nsACString *header, nsACString *_retval)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(header), _retval);

    return get_channel_http_header(&This->response_headers, header, _retval);
}

static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
        const nsACString *header, const nsACString *value, cpp_bool merge)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(header), debugstr_nsacstr(value), merge);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
        nsIHttpHeaderVisitor *aVisitor)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    TRACE("(%p)->(%p)\n", This, aVisitor);

    return visit_http_headers(&This->response_headers, aVisitor);
}

static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, cpp_bool *_retval)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);
    http_header_t *header;

    static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
    static const WCHAR no_storeW[] = {'n','o','-','s','t','o','r','e',0};

    TRACE("(%p)->(%p)\n", This, _retval);

    header = find_http_header(&This->response_headers, cache_controlW, sizeof(cache_controlW)/sizeof(WCHAR));
    *_retval = header && !strcmpiW(header->data, no_storeW);
    return NS_OK;
}

static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, cpp_bool *_retval)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, _retval);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_IsPrivateResponse(nsIHttpChannel *iface, cpp_bool *_retval)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, _retval);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsChannel_RedirectTo(nsIHttpChannel *iface, nsIURI *aTargetURI)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, aTargetURI);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannel_GetSchedulingContextID(nsIHttpChannel *iface, nsIID *aSchedulingContextID)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%p)\n", This, aSchedulingContextID);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannel_SetSchedulingContextID(nsIHttpChannel *iface, const nsIID aSchedulingContextID)
{
    nsChannel *This = impl_from_nsIHttpChannel(iface);

    FIXME("(%p)->(%s)\n", This, debugstr_guid(&aSchedulingContextID));

    return NS_ERROR_NOT_IMPLEMENTED;
}

static const nsIHttpChannelVtbl nsChannelVtbl = {
    nsChannel_QueryInterface,
    nsChannel_AddRef,
    nsChannel_Release,
    nsChannel_GetName,
    nsChannel_IsPending,
    nsChannel_GetStatus,
    nsChannel_Cancel,
    nsChannel_Suspend,
    nsChannel_Resume,
    nsChannel_GetLoadGroup,
    nsChannel_SetLoadGroup,
    nsChannel_GetLoadFlags,
    nsChannel_SetLoadFlags,
    nsChannel_GetOriginalURI,
    nsChannel_SetOriginalURI,
    nsChannel_GetURI,
    nsChannel_GetOwner,
    nsChannel_SetOwner,
    nsChannel_GetNotificationCallbacks,
    nsChannel_SetNotificationCallbacks,
    nsChannel_GetSecurityInfo,
    nsChannel_GetContentType,
    nsChannel_SetContentType,
    nsChannel_GetContentCharset,
    nsChannel_SetContentCharset,
    nsChannel_GetContentLength,
    nsChannel_SetContentLength,
    nsChannel_Open,
    nsChannel_Open2,
    nsChannel_AsyncOpen,
    nsChannel_AsyncOpen2,
    nsChannel_GetContentDisposition,
    nsChannel_SetContentDisposition,
    nsChannel_GetContentDispositionFilename,
    nsChannel_SetContentDispositionFilename,
    nsChannel_GetContentDispositionHeader,
    nsChannel_GetLoadInfo,
    nsChannel_SetLoadInfo,
    nsChannel_GetRequestMethod,
    nsChannel_SetRequestMethod,
    nsChannel_GetReferrer,
    nsChannel_SetReferrer,
    nsChannel_GetReferrerPolicy,
    nsChannel_SetReferrerWithPolicy,
    nsHttpChannel_GetProtocolVersion,
    nsHttpChannel_GetTransferSize,
    nsHttpChannel_GetDecodedBodySize,
    nsHttpChannel_GetEncodedBodySize,
    nsChannel_GetRequestHeader,
    nsChannel_SetRequestHeader,
    nsChannel_SetEmptyRequestHeader,
    nsChannel_VisitRequestHeaders,
    nsChannel_VisitNonDefaultRequestHeaders,
    nsChannel_GetAllowPipelining,
    nsChannel_SetAllowPipelining,
    nsChannel_GetAllowTLS,
    nsChannel_SetAllowTLS,
    nsChannel_GetRedirectionLimit,
    nsChannel_SetRedirectionLimit,
    nsChannel_GetResponseStatus,
    nsChannel_GetResponseStatusText,
    nsChannel_GetRequestSucceeded,
    nsChannel_GetIsMainDocumentChannel,
    nsChannel_SetIsMainDocumentChannel,
    nsChannel_GetResponseHeader,
    nsChannel_SetResponseHeader,
    nsChannel_VisitResponseHeaders,
    nsChannel_IsNoStoreResponse,
    nsChannel_IsNoCacheResponse,
    nsChannel_IsPrivateResponse,
    nsChannel_RedirectTo,
    nsHttpChannel_GetSchedulingContextID,
    nsHttpChannel_SetSchedulingContextID
};

static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface)
{
    return CONTAINING_RECORD(iface, nsChannel, nsIUploadChannel_iface);
}

static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
        void **result)
{
    nsChannel *This = impl_from_nsIUploadChannel(iface);
    return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
}

static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
{
    nsChannel *This = impl_from_nsIUploadChannel(iface);
    return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
}

static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
{
    nsChannel *This = impl_from_nsIUploadChannel(iface);
    return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
}

static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
        nsIInputStream *aStream, const nsACString *aContentType, INT64 aContentLength)
{
    nsChannel *This = impl_from_nsIUploadChannel(iface);
    const char *content_type;

    static const WCHAR content_typeW[] =
        {'C','o','n','t','e','n','t','-','T','y','p','e'};

    TRACE("(%p)->(%p %s %s)\n", This, aStream, debugstr_nsacstr(aContentType), wine_dbgstr_longlong(aContentLength));

    This->post_data_contains_headers = TRUE;

    if(aContentType) {
        nsACString_GetData(aContentType, &content_type);
        if(*content_type) {
            WCHAR *ct;

            ct = heap_strdupAtoW(content_type);
            if(!ct)
                return NS_ERROR_UNEXPECTED;

            set_http_header(&This->request_headers, content_typeW,
                    sizeof(content_typeW)/sizeof(WCHAR), ct, strlenW(ct));
            heap_free(ct);
            This->post_data_contains_headers = FALSE;
        }
    }

    if(aContentLength != -1)
        FIXME("Unsupported acontentLength = %s\n", wine_dbgstr_longlong(aContentLength));

    if(This->post_data_stream)
        nsIInputStream_Release(This->post_data_stream);
    This->post_data_stream = aStream;
    if(aStream)
        nsIInputStream_AddRef(aStream);

    This->request_method = METHOD_POST;
    return NS_OK;
}

static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
        nsIInputStream **aUploadStream)
{
    nsChannel *This = impl_from_nsIUploadChannel(iface);

    TRACE("(%p)->(%p)\n", This, aUploadStream);

    if(This->post_data_stream)
        nsIInputStream_AddRef(This->post_data_stream);

    *aUploadStream = This->post_data_stream;
    return NS_OK;
}

static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
    nsUploadChannel_QueryInterface,
    nsUploadChannel_AddRef,
    nsUploadChannel_Release,
    nsUploadChannel_SetUploadStream,
    nsUploadChannel_GetUploadStream
};

static inline nsChannel *impl_from_nsIHttpChannelInternal(nsIHttpChannelInternal *iface)
{
    return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannelInternal_iface);
}

static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
        void **result)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
}

static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
}

static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
}

static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->()\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->()\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->()\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->()\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_TakeAllSecurityMessages(nsIHttpChannelInternal *iface, void *aMessages)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->()\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->()\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->()\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 *aThirdPartyFlags)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aThirdPartyFlags);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetThirdPartyFlags(nsIHttpChannelInternal *iface, UINT32 aThirdPartyFlags)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%x)\n", This, aThirdPartyFlags);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool *aForceThirdPartyCookie)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->()\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool aForceThirdPartyCookie)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->()\n", This);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetCanceled(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->(%p)\n", This, aCanceled);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->(%p)\n", This, aCanceled);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool aCanceled)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->(%x)\n", This, aCanceled);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetLocalAddress(nsIHttpChannelInternal *iface, nsACString *aLocalAddress)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->(%p)\n", This, aLocalAddress);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetLocalPort(nsIHttpChannelInternal *iface, LONG *aLocalPort)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->(%p)\n", This, aLocalPort);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetRemoteAddress(nsIHttpChannelInternal *iface, nsACString *aRemoteAddress)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->(%p)\n", This, aRemoteAddress);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetRemotePort(nsIHttpChannelInternal *iface, LONG *aRemotePort)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->(%p)\n", This, aRemotePort);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetCacheKeysRedirectChain(nsIHttpChannelInternal *iface, void *cacheKeys)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);

    FIXME("(%p)->(%p)\n", This, cacheKeys);

    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_HTTPUpgrade(nsIHttpChannelInternal *iface,
        const nsACString *aProtocolName, nsIHttpUpgradeListener *aListener)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_nsacstr(aProtocolName), aListener);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool *aAllowSpdy)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aAllowSpdy);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool aAllowSpdy)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%x)\n", This, aAllowSpdy);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
        cpp_bool *aResponseTimeoutEnabled)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aResponseTimeoutEnabled);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetResponseTimeoutEnabled(nsIHttpChannelInternal *iface,
        cpp_bool aResponseTimeoutEnabled)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%x)\n", This, aResponseTimeoutEnabled);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetInitialRwin(nsIHttpChannelInternal *iface,
        UINT32 *aInitialRwin)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aInitialRwin);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetInitialRwin(nsIHttpChannelInternal *iface,
        UINT32 aInitialRwin)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%x)\n", This, aInitialRwin);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetApiRedirectToURI(nsIHttpChannelInternal *iface, nsIURI **aApiRedirectToURI)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aApiRedirectToURI);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool *aAllowAltSvc)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aAllowAltSvc);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetAllowAltSvc(nsIHttpChannelInternal *iface, cpp_bool aAllowAltSvc)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%x)\n", This, aAllowAltSvc);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetLastModifiedTime(nsIHttpChannelInternal *iface, PRTime *aLastModifiedTime)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aLastModifiedTime);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_ForceIntercepted(nsIHttpChannelInternal *iface, UINT64 aInterceptionID)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aInterceptionID));
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetResponseSynthesized(nsIHttpChannelInternal *iface, cpp_bool *ResponseSynthesized)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p, %p)\n", This, ResponseSynthesized);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
        cpp_bool *aCorsIncludeCredentials)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aCorsIncludeCredentials);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetCorsIncludeCredentials(nsIHttpChannelInternal *iface,
        cpp_bool aCorsIncludeCredentials)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    TRACE("(%p)->(%x)\n", This, aCorsIncludeCredentials);
    return NS_OK;
}

static nsresult NSAPI nsHttpChannelInternal_GetCorsMode(nsIHttpChannelInternal *iface, UINT32 *aCorsMode)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aCorsMode);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetCorsMode(nsIHttpChannelInternal *iface, UINT32 aCorsMode)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    TRACE("(%p)->(%d)\n", This, aCorsMode);
    return NS_OK;
}

static nsresult NSAPI nsHttpChannelInternal_GetRedirectMode(nsIHttpChannelInternal *iface, UINT32 *aRedirectMode)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aRedirectMode);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetRedirectMode(nsIHttpChannelInternal *iface, UINT32 aRedirectMode)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%d)\n", This, aRedirectMode);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetTopWindowURI(nsIHttpChannelInternal *iface, nsIURI **aTopWindowURI)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aTopWindowURI);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetNetworkInterfaceId(nsIHttpChannelInternal *iface,
        nsACString *aNetworkInterfaceId)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aNetworkInterfaceId);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetNetworkInterfaceId(nsIHttpChannelInternal *iface,
        const nsACString *aNetworkInterfaceId)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aNetworkInterfaceId));
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetProxyURI(nsIHttpChannelInternal *iface, nsIURI **aProxyURI)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aProxyURI);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetCorsPreflightParameters(nsIHttpChannelInternal *iface,
        const void /*nsTArray<nsCString>*/ *unsafeHeaders)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, unsafeHeaders);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_GetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool *aBlockAuthPrompt)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%p)\n", This, aBlockAuthPrompt);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsHttpChannelInternal_SetBlockAuthPrompt(nsIHttpChannelInternal *iface, cpp_bool aBlockAuthPrompt)
{
    nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
    FIXME("(%p)->(%x)\n", This, aBlockAuthPrompt);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
    nsHttpChannelInternal_QueryInterface,
    nsHttpChannelInternal_AddRef,
    nsHttpChannelInternal_Release,
    nsHttpChannelInternal_GetDocumentURI,
    nsHttpChannelInternal_SetDocumentURI,
    nsHttpChannelInternal_GetRequestVersion,
    nsHttpChannelInternal_GetResponseVersion,
    nsHttpChannelInternal_TakeAllSecurityMessages,
    nsHttpChannelInternal_SetCookie,
    nsHttpChannelInternal_SetupFallbackChannel,
    nsHttpChannelInternal_GetThirdPartyFlags,
    nsHttpChannelInternal_SetThirdPartyFlags,
    nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
    nsHttpChannelInternal_SetForceAllowThirdPartyCookie,
    nsHttpChannelInternal_GetCanceled,
    nsHttpChannelInternal_GetChannelIsForDownload,
    nsHttpChannelInternal_SetChannelIsForDownload,
    nsHttpChannelInternal_GetLocalAddress,
    nsHttpChannelInternal_GetLocalPort,
    nsHttpChannelInternal_GetRemoteAddress,
    nsHttpChannelInternal_GetRemotePort,
    nsHttpChannelInternal_SetCacheKeysRedirectChain,
    nsHttpChannelInternal_HTTPUpgrade,
    nsHttpChannelInternal_GetAllowSpdy,
    nsHttpChannelInternal_SetAllowSpdy,
    nsHttpChannelInternal_GetResponseTimeoutEnabled,
    nsHttpChannelInternal_SetResponseTimeoutEnabled,
    nsHttpChannelInternal_GetInitialRwin,
    nsHttpChannelInternal_SetInitialRwin,
    nsHttpChannelInternal_GetApiRedirectToURI,
    nsHttpChannelInternal_GetAllowAltSvc,
    nsHttpChannelInternal_SetAllowAltSvc,
    nsHttpChannelInternal_GetLastModifiedTime,
    nsHttpChannelInternal_ForceIntercepted,
    nsHttpChannelInternal_GetResponseSynthesized,
    nsHttpChannelInternal_GetCorsIncludeCredentials,
    nsHttpChannelInternal_SetCorsIncludeCredentials,
    nsHttpChannelInternal_GetCorsMode,
    nsHttpChannelInternal_SetCorsMode,
    nsHttpChannelInternal_GetRedirectMode,
    nsHttpChannelInternal_SetRedirectMode,
    nsHttpChannelInternal_GetTopWindowURI,
    nsHttpChannelInternal_GetNetworkInterfaceId,
    nsHttpChannelInternal_SetNetworkInterfaceId,
    nsHttpChannelInternal_GetProxyURI,
    nsHttpChannelInternal_SetCorsPreflightParameters,
    nsHttpChannelInternal_GetBlockAuthPrompt,
    nsHttpChannelInternal_SetBlockAuthPrompt
};


static void invalidate_uri(nsWineURI *This)
{
    if(This->uri) {
        IUri_Release(This->uri);
        This->uri = NULL;
    }
}

static BOOL ensure_uri_builder(nsWineURI *This)
{
    if(!This->is_mutable) {
        WARN("Not mutable URI\n");
        return FALSE;
    }

    if(!This->uri_builder) {
        HRESULT hres;

        if(!ensure_uri(This))
            return FALSE;

        hres = CreateIUriBuilder(This->uri, 0, 0, &This->uri_builder);
        if(FAILED(hres)) {
            WARN("CreateIUriBuilder failed: %08x\n", hres);
            return FALSE;
        }
    }

    invalidate_uri(This);
    return TRUE;
}

static nsresult get_uri_string(nsWineURI *This, Uri_PROPERTY prop, nsACString *ret)
{
    char *vala;
    BSTR val;
    HRESULT hres;

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_GetPropertyBSTR(This->uri, prop, &val, 0);
    if(FAILED(hres)) {
        WARN("GetPropertyBSTR failed: %08x\n", hres);
        return NS_ERROR_UNEXPECTED;
    }

    vala = heap_strdupWtoU(val);
    SysFreeString(val);
    if(!vala)
        return NS_ERROR_OUT_OF_MEMORY;

    TRACE("ret %s\n", debugstr_a(vala));
    nsACString_SetData(ret, vala);
    heap_free(vala);
    return NS_OK;
}

static inline nsWineURI *impl_from_nsIFileURL(nsIFileURL *iface)
{
    return CONTAINING_RECORD(iface, nsWineURI, nsIFileURL_iface);
}

static nsresult NSAPI nsURI_QueryInterface(nsIFileURL *iface, nsIIDRef riid, void **result)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    *result = NULL;

    if(IsEqualGUID(&IID_nsISupports, riid)) {
        TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
        *result = &This->nsIFileURL_iface;
    }else if(IsEqualGUID(&IID_nsIURI, riid)) {
        TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
        *result = &This->nsIFileURL_iface;
    }else if(IsEqualGUID(&IID_nsIURL, riid)) {
        TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
        *result = &This->nsIFileURL_iface;
    }else if(IsEqualGUID(&IID_nsIFileURL, riid)) {
        TRACE("(%p)->(IID_nsIFileURL %p)\n", This, result);
        *result = This->scheme == URL_SCHEME_FILE ? &This->nsIFileURL_iface : NULL;
    }else if(IsEqualGUID(&IID_nsIMutable, riid)) {
        TRACE("(%p)->(IID_nsIMutable %p)\n", This, result);
        *result = &This->nsIStandardURL_iface;
    }else if(IsEqualGUID(&IID_nsIStandardURL, riid)) {
        TRACE("(%p)->(IID_nsIStandardURL %p)\n", This, result);
        *result = &This->nsIStandardURL_iface;
    }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
        TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
        *result = This;
    }

    if(*result) {
        nsIFileURL_AddRef(&This->nsIFileURL_iface);
        return NS_OK;
    }

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
    return NS_NOINTERFACE;
}

static nsrefcnt NSAPI nsURI_AddRef(nsIFileURL *iface)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static nsrefcnt NSAPI nsURI_Release(nsIFileURL *iface)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        if(This->window_ref)
            windowref_release(This->window_ref);
        if(This->container)
            nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
        if(This->uri)
            IUri_Release(This->uri);
        if(This->uri_builder)
            IUriBuilder_Release(This->uri_builder);
        heap_free(This->origin_charset);
        heap_free(This);
    }

    return ref;
}

static nsresult NSAPI nsURI_GetSpec(nsIFileURL *iface, nsACString *aSpec)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%p)\n", This, aSpec);

    return get_uri_string(This, Uri_PROPERTY_DISPLAY_URI, aSpec);
}

static nsresult NSAPI nsURI_SetSpec(nsIFileURL *iface, const nsACString *aSpec)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const char *speca;
    WCHAR *spec;
    IUri *uri;
    HRESULT hres;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aSpec));

    if(!This->is_mutable)
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aSpec, &speca);
    spec = heap_strdupUtoW(speca);
    if(!spec)
        return NS_ERROR_OUT_OF_MEMORY;

    hres = create_uri(spec, 0, &uri);
    heap_free(spec);
    if(FAILED(hres)) {
        WARN("create_uri failed: %08x\n", hres);
        return NS_ERROR_FAILURE;
    }

    invalidate_uri(This);
    if(This->uri_builder) {
        IUriBuilder_Release(This->uri_builder);
        This->uri_builder = NULL;
    }

    This->uri = uri;
    return NS_OK;
}

static nsresult NSAPI nsURI_GetPrePath(nsIFileURL *iface, nsACString *aPrePath)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    IUriBuilder *uri_builder;
    BSTR display_uri;
    IUri *uri;
    int len;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, aPrePath);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = CreateIUriBuilder(This->uri, 0, 0, &uri_builder);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_PATH|Uri_HAS_QUERY|Uri_HAS_FRAGMENT);
    if(SUCCEEDED(hres))
        hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &uri);
    IUriBuilder_Release(uri_builder);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    hres = IUri_GetDisplayUri(uri, &display_uri);
    IUri_Release(uri);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    /* Remove trailing slash that may be appended as default path. */
    len = SysStringLen(display_uri);
    if(len && display_uri[len-1] == '/')
        display_uri[len-1] = 0;

    nsres = return_wstr_nsacstr(aPrePath, display_uri, -1);
    SysFreeString(display_uri);
    return nsres;
}

static nsresult NSAPI nsURI_GetScheme(nsIFileURL *iface, nsACString *aScheme)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    DWORD scheme;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, aScheme);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_GetScheme(This->uri, &scheme);
    if(FAILED(hres)) {
        WARN("GetScheme failed: %08x\n", hres);
        return NS_ERROR_UNEXPECTED;
    }

    if(scheme == URL_SCHEME_ABOUT) {
        nsACString_SetData(aScheme, "wine");
        return NS_OK;
    }

    return get_uri_string(This, Uri_PROPERTY_SCHEME_NAME, aScheme);
}

static nsresult NSAPI nsURI_SetScheme(nsIFileURL *iface, const nsACString *aScheme)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const char *schemea;
    WCHAR *scheme;
    HRESULT hres;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aScheme));

    if(!ensure_uri_builder(This))
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aScheme, &schemea);
    scheme = heap_strdupUtoW(schemea);
    if(!scheme)
        return NS_ERROR_OUT_OF_MEMORY;

    hres = IUriBuilder_SetSchemeName(This->uri_builder, scheme);
    heap_free(scheme);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    return NS_OK;
}

static nsresult NSAPI nsURI_GetUserPass(nsIFileURL *iface, nsACString *aUserPass)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    BSTR user, pass;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, aUserPass);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_GetUserName(This->uri, &user);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    hres = IUri_GetPassword(This->uri, &pass);
    if(FAILED(hres)) {
        SysFreeString(user);
        return NS_ERROR_FAILURE;
    }

    if(*user || *pass) {
        FIXME("Construct user:pass string\n");
    }else {
        nsACString_SetData(aUserPass, "");
    }

    SysFreeString(user);
    SysFreeString(pass);
    return NS_OK;
}

static nsresult NSAPI nsURI_SetUserPass(nsIFileURL *iface, const nsACString *aUserPass)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    WCHAR *user = NULL, *pass = NULL, *buf = NULL;
    const char *user_pass;
    HRESULT hres;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUserPass));

    if(!ensure_uri_builder(This))
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aUserPass, &user_pass);
    if(*user_pass) {
        WCHAR *ptr;

        buf = heap_strdupUtoW(user_pass);
        if(!buf)
            return NS_ERROR_OUT_OF_MEMORY;

        ptr = strchrW(buf, ':');
        if(!ptr) {
            user = buf;
        }else if(ptr != buf) {
            *ptr++ = 0;
            user = buf;
            if(*ptr)
                pass = ptr;
        }else {
            pass = buf+1;
        }
    }

    hres = IUriBuilder_SetUserName(This->uri_builder, user);
    if(SUCCEEDED(hres))
        hres = IUriBuilder_SetPassword(This->uri_builder, pass);

    heap_free(buf);
    return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
}

static nsresult NSAPI nsURI_GetUsername(nsIFileURL *iface, nsACString *aUsername)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%p)\n", This, aUsername);

    return get_uri_string(This, Uri_PROPERTY_USER_NAME, aUsername);
}

static nsresult NSAPI nsURI_SetUsername(nsIFileURL *iface, const nsACString *aUsername)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const char *usera;
    WCHAR *user;
    HRESULT hres;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUsername));

    if(!ensure_uri_builder(This))
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aUsername, &usera);
    user = heap_strdupUtoW(usera);
    if(!user)
        return NS_ERROR_OUT_OF_MEMORY;

    hres = IUriBuilder_SetUserName(This->uri_builder, user);
    heap_free(user);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    return NS_OK;
}

static nsresult NSAPI nsURI_GetPassword(nsIFileURL *iface, nsACString *aPassword)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%p)\n", This, aPassword);

    return get_uri_string(This, Uri_PROPERTY_PASSWORD, aPassword);
}

static nsresult NSAPI nsURI_SetPassword(nsIFileURL *iface, const nsACString *aPassword)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const char *passa;
    WCHAR *pass;
    HRESULT hres;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPassword));

    if(!ensure_uri_builder(This))
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aPassword, &passa);
    pass = heap_strdupUtoW(passa);
    if(!pass)
        return NS_ERROR_OUT_OF_MEMORY;

    hres = IUriBuilder_SetPassword(This->uri_builder, pass);
    heap_free(pass);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    return NS_OK;
}

static nsresult NSAPI nsURI_GetHostPort(nsIFileURL *iface, nsACString *aHostPort)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const WCHAR *ptr;
    char *vala;
    BSTR val;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, aHostPort);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_GetAuthority(This->uri, &val);
    if(FAILED(hres)) {
        WARN("GetAuthority failed: %08x\n", hres);
        return NS_ERROR_UNEXPECTED;
    }

    ptr = strchrW(val, '@');
    if(!ptr)
        ptr = val;

    vala = heap_strdupWtoU(ptr);
    SysFreeString(val);
    if(!vala)
        return NS_ERROR_OUT_OF_MEMORY;

    TRACE("ret %s\n", debugstr_a(vala));
    nsACString_SetData(aHostPort, vala);
    heap_free(vala);
    return NS_OK;
}

static nsresult NSAPI nsURI_SetHostPort(nsIFileURL *iface, const nsACString *aHostPort)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aHostPort));

    /* Not implemented by Gecko */
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURI_GetHost(nsIFileURL *iface, nsACString *aHost)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%p)\n", This, aHost);

    return get_uri_string(This, Uri_PROPERTY_HOST, aHost);
}

static nsresult NSAPI nsURI_SetHost(nsIFileURL *iface, const nsACString *aHost)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const char *hosta;
    WCHAR *host;
    HRESULT hres;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aHost));

    if(!ensure_uri_builder(This))
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aHost, &hosta);
    host = heap_strdupUtoW(hosta);
    if(!host)
        return NS_ERROR_OUT_OF_MEMORY;

    hres = IUriBuilder_SetHost(This->uri_builder, host);
    heap_free(host);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    return NS_OK;
}

static nsresult NSAPI nsURI_GetPort(nsIFileURL *iface, LONG *aPort)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    DWORD port;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, aPort);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_GetPort(This->uri, &port);
    if(FAILED(hres)) {
        WARN("GetPort failed: %08x\n", hres);
        return NS_ERROR_UNEXPECTED;
    }

    *aPort = port ? port : -1;
    return NS_OK;
}

static nsresult NSAPI nsURI_SetPort(nsIFileURL *iface, LONG aPort)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    HRESULT hres;

    TRACE("(%p)->(%d)\n", This, aPort);

    if(!ensure_uri_builder(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUriBuilder_SetPort(This->uri_builder, aPort != -1, aPort);
    return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
}

static nsresult NSAPI nsURI_GetPath(nsIFileURL *iface, nsACString *aPath)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%p)\n", This, aPath);

    return get_uri_string(This, Uri_PROPERTY_PATH, aPath);
}

static nsresult NSAPI nsURI_SetPath(nsIFileURL *iface, const nsACString *aPath)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const char *patha;
    WCHAR *path;
    HRESULT hres;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPath));

    if(!ensure_uri_builder(This))
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aPath, &patha);
    path = heap_strdupUtoW(patha);
    if(!path)
        return NS_ERROR_OUT_OF_MEMORY;

    hres = IUriBuilder_SetPath(This->uri_builder, path);
    heap_free(path);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    return NS_OK;
}

static nsresult NSAPI nsURI_Equals(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    nsWineURI *other_obj;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p %p)\n", This, other, _retval);

    nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
    if(NS_FAILED(nsres)) {
        TRACE("Could not get nsWineURI interface\n");
        *_retval = FALSE;
        return NS_OK;
    }

    if(ensure_uri(This) && ensure_uri(other_obj)) {
        BOOL b;

        hres = IUri_IsEqual(This->uri, other_obj->uri, &b);
        if(SUCCEEDED(hres)) {
            *_retval = b;
            nsres = NS_OK;
        }else {
            nsres = NS_ERROR_FAILURE;
        }
    }else {
        nsres = NS_ERROR_UNEXPECTED;
    }

    nsIFileURL_Release(&other_obj->nsIFileURL_iface);
    return nsres;
}

static nsresult NSAPI nsURI_SchemeIs(nsIFileURL *iface, const char *scheme, cpp_bool *_retval)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
    BSTR scheme_name;
    HRESULT hres;

    TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_GetSchemeName(This->uri, &scheme_name);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    MultiByteToWideChar(CP_UTF8, 0, scheme, -1, buf, sizeof(buf)/sizeof(WCHAR));
    *_retval = !strcmpW(scheme_name, buf);
    SysFreeString(scheme_name);
    return NS_OK;
}

static nsresult NSAPI nsURI_Clone(nsIFileURL *iface, nsIURI **_retval)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    nsWineURI *wine_uri;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, _retval);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    nsres = create_nsuri(This->uri, This->window_ref ? This->window_ref->window : NULL,
            This->container, This->origin_charset, &wine_uri);
    if(NS_FAILED(nsres)) {
        WARN("create_nsuri failed: %08x\n", nsres);
        return nsres;
    }

    *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
    return NS_OK;
}

static nsresult NSAPI nsURI_Resolve(nsIFileURL *iface, const nsACString *aRelativePath,
        nsACString *_retval)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const char *patha;
    IUri *new_uri;
    WCHAR *path;
    char *reta;
    BSTR ret;
    HRESULT hres;

    TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aRelativePath), _retval);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aRelativePath, &patha);
    path = heap_strdupUtoW(patha);
    if(!path)
        return NS_ERROR_OUT_OF_MEMORY;

    hres = combine_url(This->uri, path, &new_uri);
    heap_free(path);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    hres = IUri_GetDisplayUri(new_uri, &ret);
    IUri_Release(new_uri);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    reta = heap_strdupWtoU(ret);
    SysFreeString(ret);
    if(!reta)
        return NS_ERROR_OUT_OF_MEMORY;

    TRACE("returning %s\n", debugstr_a(reta));
    nsACString_SetData(_retval, reta);
    heap_free(reta);
    return NS_OK;
}

static nsresult NSAPI nsURI_GetAsciiSpec(nsIFileURL *iface, nsACString *aAsciiSpec)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%p)\n", This, aAsciiSpec);

    return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aAsciiSpec);
}

static nsresult NSAPI nsURI_GetAsciiHostPort(nsIFileURL *iface, nsACString *aAsciiHostPort)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHostPort);

    return nsIFileURL_GetHostPort(&This->nsIFileURL_iface, aAsciiHostPort);
}

static nsresult NSAPI nsURI_GetAsciiHost(nsIFileURL *iface, nsACString *aAsciiHost)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHost);

    return get_uri_string(This, Uri_PROPERTY_HOST, aAsciiHost);
}

static nsresult NSAPI nsURI_GetOriginCharset(nsIFileURL *iface, nsACString *aOriginCharset)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%p)\n", This, aOriginCharset);

    nsACString_SetData(aOriginCharset, This->origin_charset);
    return NS_OK;
}

static nsresult NSAPI nsURL_GetRef(nsIFileURL *iface, nsACString *aRef)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    char *refa = NULL;
    BSTR ref;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, aRef);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_GetFragment(This->uri, &ref);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    refa = heap_strdupWtoU(ref);
    SysFreeString(ref);
    if(ref && !refa)
        return NS_ERROR_OUT_OF_MEMORY;

    nsACString_SetData(aRef, refa && *refa == '#' ? refa+1 : refa);
    heap_free(refa);
    return NS_OK;
}

static nsresult NSAPI nsURL_SetRef(nsIFileURL *iface, const nsACString *aRef)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const char *refa;
    WCHAR *ref;
    HRESULT hres;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));

    if(!ensure_uri_builder(This))
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aRef, &refa);
    ref = heap_strdupUtoW(refa);
    if(!ref)
        return NS_ERROR_OUT_OF_MEMORY;

    hres = IUriBuilder_SetFragment(This->uri_builder, ref);
    heap_free(ref);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    return NS_OK;
}

static nsresult NSAPI nsURI_EqualsExceptRef(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    nsWineURI *other_obj;
    nsresult nsres;

    TRACE("(%p)->(%p %p)\n", This, other, _retval);

    nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
    if(NS_FAILED(nsres)) {
        TRACE("Could not get nsWineURI interface\n");
        *_retval = FALSE;
        return NS_OK;
    }

    if(ensure_uri(This) && ensure_uri(other_obj)) {
        *_retval = compare_ignoring_frag(This->uri, other_obj->uri);
        nsres = NS_OK;
    }else {
        nsres = NS_ERROR_UNEXPECTED;
    }

    nsIFileURL_Release(&other_obj->nsIFileURL_iface);
    return nsres;
}

static nsresult NSAPI nsURI_CloneIgnoreRef(nsIFileURL *iface, nsIURI **_retval)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    nsWineURI *wine_uri;
    IUri *uri;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, _retval);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    uri = get_uri_nofrag(This->uri);
    if(!uri)
        return NS_ERROR_FAILURE;

    nsres = create_nsuri(uri, This->window_ref ? This->window_ref->window : NULL, This->container,
            This->origin_charset, &wine_uri);
    IUri_Release(uri);
    if(NS_FAILED(nsres)) {
        WARN("create_nsuri failed: %08x\n", nsres);
        return nsres;
    }

    *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
    return NS_OK;
}

static nsresult NSAPI nsURI_GetSpecIgnoringRef(nsIFileURL *iface, nsACString *aSpecIgnoringRef)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    FIXME("(%p)->(%p)\n", This, aSpecIgnoringRef);

    return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aSpecIgnoringRef);
}

static nsresult NSAPI nsURI_GetHasRef(nsIFileURL *iface, cpp_bool *aHasRef)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    BOOL b;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, aHasRef);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_HasProperty(This->uri, Uri_PROPERTY_FRAGMENT, &b);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    *aHasRef = b;
    return NS_OK;
}

static nsresult NSAPI nsURL_GetFilePath(nsIFileURL *iface, nsACString *aFilePath)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%p)\n", This, aFilePath);

    return nsIFileURL_GetPath(&This->nsIFileURL_iface, aFilePath);
}

static nsresult NSAPI nsURL_SetFilePath(nsIFileURL *iface, const nsACString *aFilePath)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));

    if(!This->is_mutable)
        return NS_ERROR_UNEXPECTED;

    return nsIFileURL_SetPath(&This->nsIFileURL_iface, aFilePath);
}

static nsresult NSAPI nsURL_GetQuery(nsIFileURL *iface, nsACString *aQuery)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    WCHAR *ptr;
    BSTR query;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, aQuery);

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_GetQuery(This->uri, &query);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    ptr = query;
    if(ptr && *ptr == '?')
        ptr++;

    nsres = return_wstr_nsacstr(aQuery, ptr, -1);
    SysFreeString(query);
    return nsres;
}

static nsresult NSAPI nsURL_SetQuery(nsIFileURL *iface, const nsACString *aQuery)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const char *querya;
    WCHAR *query;
    HRESULT hres;

    TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));

    if(!ensure_uri_builder(This))
        return NS_ERROR_UNEXPECTED;

    nsACString_GetData(aQuery, &querya);
    query = heap_strdupUtoW(querya);
    if(!query)
        return NS_ERROR_OUT_OF_MEMORY;

    hres = IUriBuilder_SetQuery(This->uri_builder, query);
    heap_free(query);
    if(FAILED(hres))
        return NS_ERROR_UNEXPECTED;

    return NS_OK;
}

static nsresult get_uri_path(nsWineURI *This, BSTR *path, const WCHAR **file, const WCHAR **ext)
{
    const WCHAR *ptr;
    HRESULT hres;

    if(!ensure_uri(This))
        return NS_ERROR_UNEXPECTED;

    hres = IUri_GetPath(This->uri, path);
    if(FAILED(hres))
        return NS_ERROR_FAILURE;

    for(ptr = *path + SysStringLen(*path)-1; ptr > *path && *ptr != '/' && *ptr != '\\'; ptr--);
    if(*ptr == '/' || *ptr == '\\')
        ptr++;
    *file = ptr;

    if(ext) {
        ptr = strrchrW(ptr, '.');
        if(!ptr)
            ptr = *path + SysStringLen(*path);
        *ext = ptr;
    }

    return NS_OK;
}

static nsresult NSAPI nsURL_GetDirectory(nsIFileURL *iface, nsACString *aDirectory)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const WCHAR *file;
    BSTR path;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, aDirectory);

    nsres = get_uri_path(This, &path, &file, NULL);
    if(NS_FAILED(nsres))
        return nsres;

    nsres = return_wstr_nsacstr(aDirectory, path, file-path);
    SysFreeString(path);
    return nsres;
}

static nsresult NSAPI nsURL_SetDirectory(nsIFileURL *iface, const nsACString *aDirectory)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));

    /* Not implemented by Gecko */
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURL_GetFileName(nsIFileURL *iface, nsACString *aFileName)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const WCHAR *file;
    BSTR path;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, aFileName);

    nsres = get_uri_path(This, &path, &file, NULL);
    if(NS_FAILED(nsres))
        return nsres;

    nsres = return_wstr_nsacstr(aFileName, file, -1);
    SysFreeString(path);
    return nsres;
}

static nsresult NSAPI nsURL_SetFileName(nsIFileURL *iface, const nsACString *aFileName)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURL_GetFileBaseName(nsIFileURL *iface, nsACString *aFileBaseName)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    const WCHAR *file, *ext;
    BSTR path;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, aFileBaseName);

    nsres = get_uri_path(This, &path, &file, &ext);
    if(NS_FAILED(nsres))
        return nsres;

    nsres = return_wstr_nsacstr(aFileBaseName, file, ext-file);
    SysFreeString(path);
    return nsres;
}

static nsresult NSAPI nsURL_SetFileBaseName(nsIFileURL *iface, const nsACString *aFileBaseName)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURL_GetFileExtension(nsIFileURL *iface, nsACString *aFileExtension)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);

    TRACE("(%p)->(%p)\n", This, aFileExtension);

    return get_uri_string(This, Uri_PROPERTY_EXTENSION, aFileExtension);
}

static nsresult NSAPI nsURL_SetFileExtension(nsIFileURL *iface, const nsACString *aFileExtension)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsURL_GetRelativeSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsFileURL_GetFile(nsIFileURL *iface, nsIFile **aFile)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    WCHAR path[MAX_PATH];
    DWORD size;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, aFile);

    hres = CoInternetParseIUri(This->uri, PARSE_PATH_FROM_URL, 0, path, sizeof(path)/sizeof(WCHAR), &size, 0);
    if(FAILED(hres)) {
        WARN("CoInternetParseIUri failed: %08x\n", hres);
        return NS_ERROR_FAILURE;
    }

    return create_nsfile(path, aFile);
}

static nsresult NSAPI nsFileURL_SetFile(nsIFileURL *iface, nsIFile *aFile)
{
    nsWineURI *This = impl_from_nsIFileURL(iface);
    FIXME("(%p)->(%p)\n", This, aFile);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static const nsIFileURLVtbl nsFileURLVtbl = {
    nsURI_QueryInterface,
    nsURI_AddRef,
    nsURI_Release,
    nsURI_GetSpec,
    nsURI_SetSpec,
    nsURI_GetPrePath,
    nsURI_GetScheme,
    nsURI_SetScheme,
    nsURI_GetUserPass,
    nsURI_SetUserPass,
    nsURI_GetUsername,
    nsURI_SetUsername,
    nsURI_GetPassword,
    nsURI_SetPassword,
    nsURI_GetHostPort,
    nsURI_SetHostPort,
    nsURI_GetHost,
    nsURI_SetHost,
    nsURI_GetPort,
    nsURI_SetPort,
    nsURI_GetPath,
    nsURI_SetPath,
    nsURI_Equals,
    nsURI_SchemeIs,
    nsURI_Clone,
    nsURI_Resolve,
    nsURI_GetAsciiSpec,
    nsURI_GetAsciiHostPort,
    nsURI_GetAsciiHost,
    nsURI_GetOriginCharset,
    nsURL_GetRef,
    nsURL_SetRef,
    nsURI_EqualsExceptRef,
    nsURI_CloneIgnoreRef,
    nsURI_GetSpecIgnoringRef,
    nsURI_GetHasRef,
    nsURL_GetFilePath,
    nsURL_SetFilePath,
    nsURL_GetQuery,
    nsURL_SetQuery,
    nsURL_GetDirectory,
    nsURL_SetDirectory,
    nsURL_GetFileName,
    nsURL_SetFileName,
    nsURL_GetFileBaseName,
    nsURL_SetFileBaseName,
    nsURL_GetFileExtension,
    nsURL_SetFileExtension,
    nsURL_GetCommonBaseSpec,
    nsURL_GetRelativeSpec,
    nsFileURL_GetFile,
    nsFileURL_SetFile
};

static inline nsWineURI *impl_from_nsIStandardURL(nsIStandardURL *iface)
{
    return CONTAINING_RECORD(iface, nsWineURI, nsIStandardURL_iface);
}

static nsresult NSAPI nsStandardURL_QueryInterface(nsIStandardURL *iface, nsIIDRef riid,
        void **result)
{
    nsWineURI *This = impl_from_nsIStandardURL(iface);
    return nsIFileURL_QueryInterface(&This->nsIFileURL_iface, riid, result);
}

static nsrefcnt NSAPI nsStandardURL_AddRef(nsIStandardURL *iface)
{
    nsWineURI *This = impl_from_nsIStandardURL(iface);
    return nsIFileURL_AddRef(&This->nsIFileURL_iface);
}

static nsrefcnt NSAPI nsStandardURL_Release(nsIStandardURL *iface)
{
    nsWineURI *This = impl_from_nsIStandardURL(iface);
    return nsIFileURL_Release(&This->nsIFileURL_iface);
}

static nsresult NSAPI nsStandardURL_GetMutable(nsIStandardURL *iface, cpp_bool *aMutable)
{
    nsWineURI *This = impl_from_nsIStandardURL(iface);

    TRACE("(%p)->(%p)\n", This, aMutable);

    *aMutable = This->is_mutable;
    return NS_OK;
}

static nsresult NSAPI nsStandardURL_SetMutable(nsIStandardURL *iface, cpp_bool aMutable)
{
    nsWineURI *This = impl_from_nsIStandardURL(iface);

    TRACE("(%p)->(%x)\n", This, aMutable);

    This->is_mutable = aMutable;
    return NS_OK;
}

static nsresult NSAPI nsStandardURL_Init(nsIStandardURL *iface, UINT32 aUrlType, LONG aDefaultPort,
        const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
{
    nsWineURI *This = impl_from_nsIStandardURL(iface);
    FIXME("(%p)->(%d %d %s %s %p)\n", This, aUrlType, aDefaultPort, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsStandardURL_SetDefaultPort(nsIStandardURL *iface, LONG aNewDefaultPort)
{
    nsWineURI *This = impl_from_nsIStandardURL(iface);
    FIXME("(%p)->(%d)\n", This, aNewDefaultPort);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static const nsIStandardURLVtbl nsStandardURLVtbl = {
    nsStandardURL_QueryInterface,
    nsStandardURL_AddRef,
    nsStandardURL_Release,
    nsStandardURL_GetMutable,
    nsStandardURL_SetMutable,
    nsStandardURL_Init,
    nsStandardURL_SetDefaultPort
};

static nsresult create_nsuri(IUri *iuri, HTMLOuterWindow *window, NSContainer *container,
        const char *origin_charset, nsWineURI **_retval)
{
    nsWineURI *ret;
    HRESULT hres;

    ret = heap_alloc_zero(sizeof(nsWineURI));
    if(!ret)
        return NS_ERROR_OUT_OF_MEMORY;

    ret->nsIFileURL_iface.lpVtbl = &nsFileURLVtbl;
    ret->nsIStandardURL_iface.lpVtbl = &nsStandardURLVtbl;
    ret->ref = 1;
    ret->is_mutable = TRUE;

    set_uri_nscontainer(ret, container);
    set_uri_window(ret, window);

    IUri_AddRef(iuri);
    ret->uri = iuri;

    hres = IUri_GetScheme(iuri, &ret->scheme);
    if(FAILED(hres))
        ret->scheme = URL_SCHEME_UNKNOWN;

    if(origin_charset && *origin_charset && strcmp(origin_charset, "UTF-8")) {
        ret->origin_charset = heap_strdupA(origin_charset);
        if(!ret->origin_charset) {
            nsIFileURL_Release(&ret->nsIFileURL_iface);
            return NS_ERROR_OUT_OF_MEMORY;
        }
    }

    TRACE("retval=%p\n", ret);
    *_retval = ret;
    return NS_OK;
}

HRESULT create_doc_uri(HTMLOuterWindow *window, IUri *iuri, nsWineURI **ret)
{
    nsWineURI *uri;
    nsresult nsres;

    nsres = create_nsuri(iuri, window, window->doc_obj ? window->doc_obj->nscontainer : NULL,
            NULL, &uri);
    if(NS_FAILED(nsres))
        return E_FAIL;

    uri->is_doc_uri = TRUE;

    *ret = uri;
    return S_OK;
}

static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
{
    nsChannel *channel;

    if(!ensure_uri(uri))
        return NS_ERROR_UNEXPECTED;

    channel = heap_alloc_zero(sizeof(nsChannel));
    if(!channel)
        return NS_ERROR_OUT_OF_MEMORY;

    channel->nsIHttpChannel_iface.lpVtbl = &nsChannelVtbl;
    channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
    channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
    channel->ref = 1;
    channel->request_method = METHOD_GET;
    list_init(&channel->response_headers);
    list_init(&channel->request_headers);

    nsIFileURL_AddRef(&uri->nsIFileURL_iface);
    channel->uri = uri;

    *ret = channel;
    return NS_OK;
}

HRESULT create_redirect_nschannel(const WCHAR *url, nsChannel *orig_channel, nsChannel **ret)
{
    HTMLOuterWindow *window = NULL;
    nsChannel *channel;
    nsWineURI *uri;
    IUri *iuri;
    nsresult nsres;
    HRESULT hres;

    hres = create_uri(url, 0, &iuri);
    if(FAILED(hres))
        return hres;

    if(orig_channel->uri->window_ref)
        window = orig_channel->uri->window_ref->window;
    nsres = create_nsuri(iuri, window, NULL, NULL, &uri);
    IUri_Release(iuri);
    if(NS_FAILED(nsres))
        return E_FAIL;

    nsres = create_nschannel(uri, &channel);
    nsIFileURL_Release(&uri->nsIFileURL_iface);
    if(NS_FAILED(nsres))
        return E_FAIL;

    if(orig_channel->load_group) {
        nsILoadGroup_AddRef(orig_channel->load_group);
        channel->load_group = orig_channel->load_group;
    }

    if(orig_channel->notif_callback) {
        nsIInterfaceRequestor_AddRef(orig_channel->notif_callback);
        channel->notif_callback = orig_channel->notif_callback;
    }

    channel->load_flags = orig_channel->load_flags | LOAD_REPLACE;

    if(orig_channel->request_method == METHOD_POST)
        FIXME("unsupported POST method\n");

    if(orig_channel->original_uri) {
        nsIURI_AddRef(orig_channel->original_uri);
        channel->original_uri = orig_channel->original_uri;
    }

    if(orig_channel->referrer) {
        nsIURI_AddRef(orig_channel->referrer);
        channel->referrer = orig_channel->referrer;
    }

    *ret = channel;
    return S_OK;
}

typedef struct {
    nsIProtocolHandler nsIProtocolHandler_iface;

    LONG ref;

    nsIProtocolHandler *nshandler;
} nsProtocolHandler;

static inline nsProtocolHandler *impl_from_nsIProtocolHandler(nsIProtocolHandler *iface)
{
    return CONTAINING_RECORD(iface, nsProtocolHandler, nsIProtocolHandler_iface);
}

static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
        void **result)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);

    *result = NULL;

    if(IsEqualGUID(&IID_nsISupports, riid)) {
        TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
        *result = &This->nsIProtocolHandler_iface;
    }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
        TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
        *result = &This->nsIProtocolHandler_iface;
    }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
        TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
        return NS_NOINTERFACE;
    }

    if(*result) {
        nsISupports_AddRef((nsISupports*)*result);
        return NS_OK;
    }

    WARN("(%s %p)\n", debugstr_guid(riid), result);
    return NS_NOINTERFACE;
}

static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        if(This->nshandler)
            nsIProtocolHandler_Release(This->nshandler);
        heap_free(This);
    }

    return ref;
}

static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);

    TRACE("(%p)->(%p)\n", This, aScheme);

    if(This->nshandler)
        return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
        LONG *aDefaultPort)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);

    TRACE("(%p)->(%p)\n", This, aDefaultPort);

    if(This->nshandler)
        return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
                                                         UINT32 *aProtocolFlags)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);

    TRACE("(%p)->(%p)\n", This, aProtocolFlags);

    if(This->nshandler)
        return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
        const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);

    TRACE("((%p)->%s %s %p %p)\n", This, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
          aBaseURI, _retval);

    if(This->nshandler)
        return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsProtocolHandler_NewChannel2(nsIProtocolHandler *iface,
        nsIURI *aURI, nsILoadInfo *aLoadInfo, nsIChannel **_retval)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);

    TRACE("(%p)->(%p %p %p)\n", This, aURI, aLoadInfo, _retval);

    if(This->nshandler)
        return nsIProtocolHandler_NewChannel2(This->nshandler, aURI, aLoadInfo, _retval);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
        nsIURI *aURI, nsIChannel **_retval)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);

    TRACE("(%p)->(%p %p)\n", This, aURI, _retval);

    if(This->nshandler)
        return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
        LONG port, const char *scheme, cpp_bool *_retval)
{
    nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);

    TRACE("(%p)->(%d %s %p)\n", This, port, debugstr_a(scheme), _retval);

    if(This->nshandler)
        return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
    return NS_ERROR_NOT_IMPLEMENTED;
}

static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
    nsProtocolHandler_QueryInterface,
    nsProtocolHandler_AddRef,
    nsProtocolHandler_Release,
    nsProtocolHandler_GetScheme,
    nsProtocolHandler_GetDefaultPort,
    nsProtocolHandler_GetProtocolFlags,
    nsProtocolHandler_NewURI,
    nsProtocolHandler_NewChannel2,
    nsProtocolHandler_NewChannel,
    nsProtocolHandler_AllowPort
};

static nsresult NSAPI nsIOServiceHook_QueryInterface(nsIIOServiceHook *iface, nsIIDRef riid,
        void **result)
{
    if(IsEqualGUID(&IID_nsISupports, riid)) {
        TRACE("(IID_nsISupports %p)\n", result);
        *result = iface;
    }else if(IsEqualGUID(&IID_nsIIOServiceHook, riid)) {
        TRACE("(IID_nsIIOServiceHook %p)\n", result);
        *result = iface;
    }else {
        ERR("(%s %p)\n", debugstr_guid(riid), result);
        *result = NULL;
        return NS_NOINTERFACE;
    }

    nsISupports_AddRef((nsISupports*)*result);
    return NS_OK;
}

static nsrefcnt NSAPI nsIOServiceHook_AddRef(nsIIOServiceHook *iface)
{
    return 2;
}

static nsrefcnt NSAPI nsIOServiceHook_Release(nsIIOServiceHook *iface)
{
    return 1;
}

static nsresult NSAPI nsIOServiceHook_NewChannel(nsIIOServiceHook *iface, nsIURI *aURI,
        nsILoadInfo *aLoadInfo, nsIChannel **_retval)
{
    nsWineURI *wine_uri;
    nsChannel *ret;
    nsresult nsres;

    TRACE("(%p %p %p)\n", aURI, aLoadInfo, _retval);

    nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
    if(NS_FAILED(nsres)) {
        TRACE("Could not get nsWineURI: %08x\n", nsres);
        return NS_SUCCESS_DEFAULT_ACTION;
    }

    nsres = create_nschannel(wine_uri, &ret);
    nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
    if(NS_FAILED(nsres))
        return nsres;

    nsIURI_AddRef(aURI);
    ret->original_uri = aURI;

    if(aLoadInfo)
        nsIHttpChannel_SetLoadInfo(&ret->nsIHttpChannel_iface, aLoadInfo);

    *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface;
    return NS_OK;
}

static nsresult NSAPI nsIOServiceHook_GetProtocolHandler(nsIIOServiceHook *iface, nsIProtocolHandler *aHandler,
        nsIProtocolHandler **_retval)
{
    nsIExternalProtocolHandler *nsexthandler;
    nsProtocolHandler *ret;
    nsresult nsres;

    TRACE("(%p %p)\n", aHandler, _retval);

    nsres = nsIProtocolHandler_QueryInterface(aHandler, &IID_nsIExternalProtocolHandler, (void**)&nsexthandler);
    if(NS_FAILED(nsres)) {
        nsIProtocolHandler_AddRef(aHandler);
        *_retval = aHandler;
        return NS_OK;
    }

    nsIExternalProtocolHandler_Release(nsexthandler);

    ret = heap_alloc(sizeof(nsProtocolHandler));
    if(!ret)
        return NS_ERROR_OUT_OF_MEMORY;

    ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl;
    ret->ref = 1;
    nsIProtocolHandler_AddRef(aHandler);
    ret->nshandler = aHandler;


    *_retval = &ret->nsIProtocolHandler_iface;
    TRACE("return %p\n", *_retval);
    return NS_OK;
}

static BOOL is_gecko_special_uri(const char *spec)
{
    static const char *special_schemes[] = {"chrome:", "data:", "jar:", "moz-safe-about", "resource:", "javascript:", "wyciwyg:"};
    unsigned int i;

    for(i=0; i < sizeof(special_schemes)/sizeof(*special_schemes); i++) {
        if(!strncasecmp(spec, special_schemes[i], strlen(special_schemes[i])))
            return TRUE;
    }

    if(!strncasecmp(spec, "file:", 5)) {
        const char *ptr = spec+5;
        while(*ptr == '/')
            ptr++;
        return is_gecko_path(ptr);
    }

    return FALSE;
}

static nsresult NSAPI nsIOServiceHook_NewURI(nsIIOServiceHook *iface, const nsACString *aSpec,
        const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
{
    nsWineURI *wine_uri, *base_wine_uri = NULL;
    WCHAR new_spec[INTERNET_MAX_URL_LENGTH];
    HTMLOuterWindow *window = NULL;
    const char *spec = NULL;
    UINT cp = CP_UTF8;
    IUri *urlmon_uri;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
          aBaseURI, _retval);

    nsACString_GetData(aSpec, &spec);
    if(is_gecko_special_uri(spec))
        return NS_SUCCESS_DEFAULT_ACTION;

    if(!strncmp(spec, "wine:", 5))
        spec += 5;

    if(aBaseURI) {
        nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
        if(NS_SUCCEEDED(nsres)) {
            if(!ensure_uri(base_wine_uri))
                return NS_ERROR_UNEXPECTED;
            if(base_wine_uri->window_ref)
                window = base_wine_uri->window_ref->window;
        }else {
            WARN("Could not get base nsWineURI: %08x\n", nsres);
        }
    }

    if(aOriginCharset && *aOriginCharset && strncasecmp(aOriginCharset, "utf", 3)) {
        BSTR charset;
        int len;

        len = MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, NULL, 0);
        charset = SysAllocStringLen(NULL, len-1);
        if(!charset)
            return NS_ERROR_OUT_OF_MEMORY;
        MultiByteToWideChar(CP_UTF8, 0, aOriginCharset, -1, charset, len);

        cp = cp_from_charset_string(charset);

        SysFreeString(charset);
    }

    MultiByteToWideChar(cp, 0, spec, -1, new_spec, sizeof(new_spec)/sizeof(WCHAR));

    if(base_wine_uri) {
        hres = combine_url(base_wine_uri->uri, new_spec, &urlmon_uri);
    }else {
        hres = create_uri(new_spec, 0, &urlmon_uri);
        if(FAILED(hres))
            WARN("create_uri failed: %08x\n", hres);
    }

    if(FAILED(hres))
        return NS_SUCCESS_DEFAULT_ACTION;

    nsres = create_nsuri(urlmon_uri, window, NULL, NULL, &wine_uri);
    IUri_Release(urlmon_uri);
    if(base_wine_uri)
        nsIFileURL_Release(&base_wine_uri->nsIFileURL_iface);
    if(NS_FAILED(nsres))
        return nsres;

    *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
    return nsres;
}

static const char *debugstr_protocol_flags(UINT32 flags)
{
    switch(flags) {
#define X(f) case f: return #f
    X(URI_STD);
    X(URI_NORELATIVE);
    X(URI_NOAUTH);
    X(ALLOWS_PROXY);
    X(ALLOWS_PROXY_HTTP);
    X(URI_INHERITS_SECURITY_CONTEXT);
    X(URI_FORBIDS_AUTOMATIC_DOCUMENT_REPLACEMENT);
    X(URI_LOADABLE_BY_ANYONE);
    X(URI_DANGEROUS_TO_LOAD);
    X(URI_IS_UI_RESOURCE);
    X(URI_IS_LOCAL_FILE);
    X(URI_LOADABLE_BY_SUBSUMERS);
    X(URI_DOES_NOT_RETURN_DATA);
    X(URI_IS_LOCAL_RESOURCE);
    X(URI_OPENING_EXECUTES_SCRIPT);
    X(URI_NON_PERSISTABLE);
    X(URI_FORBIDS_COOKIE_ACCESS);
    X(URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM);
    X(URI_SYNC_LOAD_IS_OK);
    X(URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT);
    X(URI_FETCHABLE_BY_ANYONE);
#undef X
    default:
        return wine_dbg_sprintf("%08x", flags);
    }
}

static nsresult NSAPI nsIOServiceHook_ProtocolHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
{
    TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);
    return NS_SUCCESS_DEFAULT_ACTION;
}

static nsresult NSAPI nsIOServiceHook_URIChainHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
{
    TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval);

    if(aFlags == URI_DOES_NOT_RETURN_DATA) {
        *_retval = FALSE;
        return S_OK;
    }

    return NS_SUCCESS_DEFAULT_ACTION;
}

static const nsIIOServiceHookVtbl nsIOServiceHookVtbl = {
    nsIOServiceHook_QueryInterface,
    nsIOServiceHook_AddRef,
    nsIOServiceHook_Release,
    nsIOServiceHook_NewChannel,
    nsIOServiceHook_GetProtocolHandler,
    nsIOServiceHook_NewURI,
    nsIOServiceHook_ProtocolHasFlags,
    nsIOServiceHook_URIChainHasFlags
};

static nsIIOServiceHook nsIOServiceHook = { &nsIOServiceHookVtbl };

static BOOL translate_url(HTMLDocumentObj *doc, nsWineURI *uri)
{
    OLECHAR *new_url = NULL;
    WCHAR *url;
    BOOL ret = FALSE;
    HRESULT hres;

    if(!doc->hostui || !ensure_uri(uri))
        return FALSE;

    hres = IUri_GetDisplayUri(uri->uri, &url);
    if(FAILED(hres))
        return FALSE;

    hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, url, &new_url);
    if(hres == S_OK && new_url) {
        if(strcmpW(url, new_url)) {
            FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url));
            ret = TRUE;
        }
        CoTaskMemFree(new_url);
    }

    SysFreeString(url);
    return ret;
}

nsresult on_start_uri_open(NSContainer *nscontainer, nsIURI *uri, cpp_bool *_retval)
{
    nsWineURI *wine_uri;
    nsresult nsres;

    *_retval = FALSE;

    nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
    if(NS_FAILED(nsres)) {
        WARN("Could not get nsWineURI: %08x\n", nsres);
        return NS_ERROR_NOT_IMPLEMENTED;
    }

    if(!wine_uri->is_doc_uri) {
        wine_uri->is_doc_uri = TRUE;

        if(!wine_uri->container) {
            nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
            wine_uri->container = nscontainer;
        }

        if(nscontainer->doc)
            *_retval = translate_url(nscontainer->doc, wine_uri);
    }

    nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
    return NS_OK;
}

void init_nsio(nsIComponentManager *component_manager)
{
    nsIFactory *old_factory = NULL;
    nsresult nsres;

    nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
                                               &IID_nsIFactory, (void**)&old_factory);
    if(NS_FAILED(nsres)) {
        ERR("Could not get factory: %08x\n", nsres);
        return;
    }

    nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
    if(NS_FAILED(nsres)) {
        ERR("Couldn not create nsIOService instance %08x\n", nsres);
        nsIFactory_Release(old_factory);
        return;
    }

    nsres = nsIIOService_SetHook(nsio, &nsIOServiceHook);
    assert(nsres == NS_OK);
}

void release_nsio(void)
{
    if(nsio) {
        nsIIOService_Release(nsio);
        nsio = NULL;
    }
}
