/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_registry.hxx"

#include "registry/registry.hxx"
#include "registry/reader.hxx"
#include "registry/version.h"
#include "fileurl.hxx"
#include "options.hxx"

#include <rtl/ustring.hxx>
#include <osl/diagnose.h>

#include <stdio.h>
#include <string.h>

#include <set>
#include <vector>
#include <string>

using namespace rtl;
using namespace registry::tools;

typedef std::set< rtl::OUString > StringSet;

class Options_Impl : public Options
{
public:
	explicit Options_Impl(char const * program)
		: Options(program), 
          m_bFullCheck(false),
          m_bForceOutput(false),
          m_bUnoTypeCheck(false),
          m_checkUnpublished(false)
		{}
	
    std::string const & getRegName1() const { return m_regName1; }
    std::string const & getRegName2() const { return m_regName2; }

	bool isStartKeyValid() const { return (m_startKey.getLength() > 0); }
	OUString const & getStartKey() const { return m_startKey; }
    bool matchedWithExcludeKey( const OUString& keyName) const;

	bool fullCheck() const { return m_bFullCheck; }
	bool forceOutput() const { return m_bForceOutput; }
	bool unoTypeCheck() const { return m_bUnoTypeCheck; }
    bool checkUnpublished() const { return m_checkUnpublished; }

protected:
    bool setRegName_Impl(char c, std::string const & param);

	virtual void printUsage_Impl() const;
	virtual bool initOptions_Impl (std::vector< std::string > & rArgs);
	
    std::string m_regName1;	
    std::string m_regName2;	
	OUString    m_startKey;
	StringSet	m_excludeKeys;
	bool m_bFullCheck;
	bool m_bForceOutput;
	bool m_bUnoTypeCheck;
    bool m_checkUnpublished;
};	

#define U2S( s ) OUStringToOString(s, RTL_TEXTENCODING_UTF8).getStr()

inline rtl::OUString makeOUString (std::string const & s)
{
    return rtl::OUString(s.c_str(), s.size(), RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
}

inline rtl::OUString shortName(rtl::OUString const & fullName)
{
    return fullName.copy(fullName.lastIndexOf('/') + 1);
}

bool Options_Impl::setRegName_Impl(char c, std::string const & param)
{
    bool one = (c == '1'), two = (c == '2');
    if (one)
        m_regName1 = param;
    if (two)
        m_regName2 = param;
    return (one || two);
}

//virtual
void Options_Impl::printUsage_Impl() const
{
    std::string const & rProgName = getProgramName();
    fprintf(stderr,
            "Usage: %s -r1<filename> -r2<filename> [-options] | @<filename>\n", rProgName.c_str()
            );
    fprintf(stderr,
            "    -r1<filename>  = filename specifies the name of the first registry.\n"
            "    -r2<filename>  = filename specifies the name of the second registry.\n"
            "    @<filename>    = filename specifies a command file.\n"
            "Options:\n"
            "    -s<name>  = name specifies the name of a start key. If no start key\n"
            "     |S<name>   is specified the comparison starts with the root key.\n"
            "    -x<name>  = name specifies the name of a key which won't be compared. All\n"
            "     |X<name>   subkeys won't be compared also. This option can be used more than once.\n"
            "    -f|F      = force the detailed output of any diffenrences. Default\n"
            "                is that only the number of differences is returned.\n"
            "    -c|C      = make a complete check, that means any differences will be\n"
            "                detected. Default is only a compatibility check that means\n"
            "                only UNO typelibrary entries will be checked.\n"
            "    -t|T      = make an UNO type compatiblity check. This means that registry 2\n"
            "                will be checked against registry 1. If a interface in r2 contains\n"
            "                more methods or the methods are in a different order as in r1, r2 is\n"
            "                incompatible to r1. But if a service in r2 supports more properties as\n"
            "                in r1 and the new properties are 'optional' it is compatible.\n"
            "    -u|U      = additionally check types that are unpublished in registry 1.\n"
            "    -h|-?     = print this help message and exit.\n"
            );
    fprintf(stderr,
            "\n%s Version 1.0\n\n", rProgName.c_str()
            );
}	

// virtual
bool Options_Impl::initOptions_Impl (std::vector< std::string > & rArgs)
{
    std::vector< std::string >::const_iterator first = rArgs.begin(), last = rArgs.end();
    for (; first != last; ++first)
	{
		if ((*first)[0] != '-')
		{
            return badOption("invalid", (*first).c_str());
        }
        switch ((*first)[1])
        {
        case 'r':
        case 'R':
            {
                if (!((++first != last) && ((*first)[0] != '-')))
                {
                    return badOption("invalid", (*first).c_str());
                }

                std::string option(*first), param;
                if (option.size() == 1)
                {
                    // "-r<n><space><param>"
                    if (!((++first != last) && ((*first)[0] != '-')))
                    {
                        return badOption("invalid", (*first).c_str());
                    }
                    param = (*first);
                }
                else
                {
                    // "-r<n><param>"
                    param = std::string(&(option[1]), option.size() - 1);
                }
                if (!setRegName_Impl(option[0], param))
                {
                    return badOption("invalid", option.c_str());
                }
                break;
            }
        case 's':
        case 'S':
            {
                if (!((++first != last) && ((*first)[0] != '-')))
                {
                    return badOption("invalid", (*first).c_str());
                }
                m_startKey = makeOUString(*first);
                break;
            }
        case 'x':
        case 'X':
            {
                if (!((++first != last) && ((*first)[0] != '-')))
                {
                    return badOption("invalid", (*first).c_str());
                }
                m_excludeKeys.insert(makeOUString(*first));
                break;
            }
        case 'f':
        case 'F':
            {
			    if ((*first).size() > 2)
                {
                    return badOption("invalid", (*first).c_str());
                }
                m_bForceOutput = sal_True;
                break;
            }
        case 'c':
        case 'C':
            {
			    if ((*first).size() > 2)
                {
                    return badOption("invalid", (*first).c_str());
                }
                m_bFullCheck = sal_True;
                break;
            }
        case 't':
        case 'T':
            {
			    if ((*first).size() > 2)
                {
                    return badOption("invalid", (*first).c_str());
                }
                m_bUnoTypeCheck = sal_True;
                break;
            }
        case 'u':
        case 'U':
            {
			    if ((*first).size() > 2)
                {
                    return badOption("invalid", (*first).c_str());
                }
                m_checkUnpublished = true;
                break;
            }
        case 'h':
        case '?':
            {
			    if ((*first).size() > 2)
                {
                    return badOption("invalid", (*first).c_str());
                }
                return printUsage();
                // break; // Unreachable
            }
        default:
            {
                return badOption("unknown", (*first).c_str());
                // break; // Unreachable
            }
        }
    }

    if ( m_regName1.size() == 0 )
    {
        return badOption("missing", "-r1");
    }
    if ( m_regName2.size() == 0 )
    {
        return badOption("missing", "-r2");
    }
    return true;
}

bool Options_Impl::matchedWithExcludeKey( const OUString& keyName) const
{
    if (!m_excludeKeys.empty())
    {
        StringSet::const_iterator first = m_excludeKeys.begin(), last = m_excludeKeys.end();
        for (; first != last; ++first)
        {
            if (keyName.indexOf(*first) == 0)
                return true;
        }
    }
    return false;
}

static char const * getTypeClass(RTTypeClass typeClass)
{
	switch (typeClass)
	{
		case RT_TYPE_INTERFACE:
			return "INTERFACE";
		case RT_TYPE_MODULE:
			return "MODULE";
		case RT_TYPE_STRUCT:
			return "STRUCT";
		case RT_TYPE_ENUM:
			return "ENUM";
		case RT_TYPE_EXCEPTION:
			return "EXCEPTION";
		case RT_TYPE_TYPEDEF:
			return "TYPEDEF";
		case RT_TYPE_SERVICE:
			return "SERVICE";
		case RT_TYPE_OBJECT:
			return "OBJECT";
		case RT_TYPE_CONSTANTS:
			return "CONSTANTS";
        default:
            return "INVALID";
	}
}	

static OString getFieldAccess(RTFieldAccess fieldAccess)
{
	OString ret;	
	if ( (fieldAccess & RT_ACCESS_INVALID) == RT_ACCESS_INVALID )
	{
		ret += OString("INVALID");
	}
	if ( (fieldAccess & RT_ACCESS_READONLY) == RT_ACCESS_READONLY )
	{
		ret += OString(ret.getLength() > 0 ? ",READONLY" : "READONLY");
	}
	if ( (fieldAccess & RT_ACCESS_OPTIONAL) == RT_ACCESS_OPTIONAL )
	{
		ret += OString(ret.getLength() > 0 ? ",OPTIONAL" : "OPTIONAL");
	}
	if ( (fieldAccess & RT_ACCESS_MAYBEVOID) == RT_ACCESS_MAYBEVOID )
	{
		ret += OString(ret.getLength() > 0 ? ",MAYBEVOID" : "MAYBEVOID");
	}
	if ( (fieldAccess & RT_ACCESS_BOUND) == RT_ACCESS_BOUND )
	{
		ret += OString(ret.getLength() > 0 ? ",BOUND" : "BOUND");
	}
	if ( (fieldAccess & RT_ACCESS_CONSTRAINED) == RT_ACCESS_CONSTRAINED )
	{
		ret += OString(ret.getLength() > 0 ? ",CONSTRAINED" : "CONSTRAINED");
	}
	if ( (fieldAccess & RT_ACCESS_TRANSIENT) == RT_ACCESS_TRANSIENT )
	{
		ret += OString(ret.getLength() > 0 ? ",TRANSIENT" : "TRANSIENT");
	}
	if ( (fieldAccess & RT_ACCESS_MAYBEAMBIGUOUS) == RT_ACCESS_MAYBEAMBIGUOUS )
	{
		ret += OString(ret.getLength() > 0 ? ",MAYBEAMBIGUOUS" : "MAYBEAMBIGUOUS");
	}
	if ( (fieldAccess & RT_ACCESS_MAYBEDEFAULT) == RT_ACCESS_MAYBEDEFAULT )
	{
		ret += OString(ret.getLength() > 0 ? ",MAYBEDEFAULT" : "MAYBEDEFAULT");
	}
	if ( (fieldAccess & RT_ACCESS_REMOVEABLE) == RT_ACCESS_REMOVEABLE )
	{
		ret += OString(ret.getLength() > 0 ? ",REMOVEABLE" : "REMOVEABLE");
	}
	if ( (fieldAccess & RT_ACCESS_ATTRIBUTE) == RT_ACCESS_ATTRIBUTE )
	{
		ret += OString(ret.getLength() > 0 ? ",ATTRIBUTE" : "ATTRIBUTE");
	}
	if ( (fieldAccess & RT_ACCESS_PROPERTY) == RT_ACCESS_PROPERTY )
	{
		ret += OString(ret.getLength() > 0 ? ",PROPERTY" : "PROPERTY");
	}
	if ( (fieldAccess & RT_ACCESS_CONST) == RT_ACCESS_CONST )
	{
		ret += OString(ret.getLength() > 0 ? ",CONST" : "CONST");
	}
	if ( (fieldAccess & RT_ACCESS_READWRITE) == RT_ACCESS_READWRITE )
	{
		ret += OString(ret.getLength() > 0 ? ",READWRITE" : "READWRITE");
	}
	return ret;
} 

static char const * getConstValueType(RTConstValue& constValue)
{
	switch (constValue.m_type)
	{
		case RT_TYPE_BOOL:
			return "sal_Bool";
		case RT_TYPE_BYTE:
			return "sal_uInt8";
		case RT_TYPE_INT16:
			return "sal_Int16";
		case RT_TYPE_UINT16:
			return "sal_uInt16";
		case RT_TYPE_INT32:
			return "sal_Int32";
		case RT_TYPE_UINT32:
			return "sal_uInt32";
//		case RT_TYPE_INT64:
//			return "sal_Int64";
//		case RT_TYPE_UINT64:
//			return "sal_uInt64";
		case RT_TYPE_FLOAT:
			return "float";
		case RT_TYPE_DOUBLE:
			return "double";
		case RT_TYPE_STRING:
			return "sal_Unicode*";
        default:
            return "NONE";
	}	
}	

static void printConstValue(RTConstValue& constValue)
{
	switch (constValue.m_type)
	{
		case RT_TYPE_NONE:
			fprintf(stdout, "none");
            break;
		case RT_TYPE_BOOL:
			fprintf(stdout, "%s", constValue.m_value.aBool ? "TRUE" : "FALSE");
            break;
		case RT_TYPE_BYTE:
			fprintf(stdout, "%d", constValue.m_value.aByte);
            break;
		case RT_TYPE_INT16:
			fprintf(stdout, "%d", constValue.m_value.aShort);
            break;
		case RT_TYPE_UINT16:
			fprintf(stdout, "%d", constValue.m_value.aUShort);
            break;
		case RT_TYPE_INT32:
			fprintf(
                stdout, "%ld",
                sal::static_int_cast< long >(constValue.m_value.aLong));
            break;
		case RT_TYPE_UINT32:
			fprintf(
                stdout, "%lu",
                sal::static_int_cast< unsigned long >(
                    constValue.m_value.aULong));
            break;
//		case RT_TYPE_INT64:
//			fprintf(stdout, "%d", constValue.m_value.aHyper);
//		case RT_TYPE_UINT64:
//			fprintf(stdout, "%d", constValue.m_value.aUHyper);
		case RT_TYPE_FLOAT:
			fprintf(stdout, "%f", constValue.m_value.aFloat);
            break;
		case RT_TYPE_DOUBLE:
			fprintf(stdout, "%f", constValue.m_value.aDouble);
            break;
		case RT_TYPE_STRING:
			fprintf(
                stdout, "%s",
                (rtl::OUStringToOString(
                    constValue.m_value.aString, RTL_TEXTENCODING_UTF8).
                 getStr()));
            break;
        default:
            break;
	}
}

static void dumpTypeClass(sal_Bool & rbDump, RTTypeClass typeClass, OUString const & keyName)
{
    if (rbDump)
        fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName));
    rbDump = sal_False;
}

static sal_uInt32 checkConstValue(Options_Impl const & options,
                                  const OUString& keyName,
								  RTTypeClass typeClass,
								  sal_Bool & bDump,
								  RTConstValue& constValue1,
								  RTConstValue& constValue2,
								  sal_uInt16 index1)
{
	switch (constValue1.m_type)
	{
        case RT_TYPE_INVALID:
            break;
		case RT_TYPE_BOOL:
			if (constValue1.m_value.aBool != constValue2.m_value.aBool)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
                    fprintf(stdout, "  Field %d: Value1 = %s  !=  Value2 = %s\n", index1,
                            constValue1.m_value.aBool ? "TRUE" : "FALSE",
                            constValue2.m_value.aBool ? "TRUE" : "FALSE");
				}
				return 1;
			}
			break;
		case RT_TYPE_BYTE:
			if (constValue1.m_value.aByte != constValue2.m_value.aByte)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
					dumpTypeClass(bDump, typeClass, keyName);
                    fprintf(stdout, "  Field %d: Value1 = %d  !=  Value2 = %d\n", index1,
                            constValue1.m_value.aByte, constValue2.m_value.aByte);
				}
				return 1;
			}
			break;
		case RT_TYPE_INT16:
			if (constValue1.m_value.aShort != constValue2.m_value.aShort)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
                    fprintf(stdout, "  Field %d: Value1 = %d  !=  Value2 = %d\n", index1,
                            constValue1.m_value.aShort, constValue2.m_value.aShort);
				}
				return 1;
			}
			break;
		case RT_TYPE_UINT16:
			if (constValue1.m_value.aUShort != constValue2.m_value.aUShort)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
                    fprintf(stdout, "  Field %d: Value1 = %d  !=  Value2 = %d\n", index1,
                            constValue1.m_value.aUShort, constValue2.m_value.aUShort);
				}
				return 1;
			}
			break;
		case RT_TYPE_INT32:
			if (constValue1.m_value.aLong != constValue2.m_value.aLong)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
                    fprintf(stdout, "  Field %d: Value1 = %ld  !=  Value2 = %ld\n", index1,
                            sal::static_int_cast< long >(constValue1.m_value.aLong),
                            sal::static_int_cast< long >(constValue2.m_value.aLong));
				}
				return 1;
			}
			break;
		case RT_TYPE_UINT32:
			if (constValue1.m_value.aULong != constValue2.m_value.aULong)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
                    fprintf(stdout, "  Field %d: Value1 = %lu  !=  Value2 = %lu\n", index1,
                            sal::static_int_cast< unsigned long >(constValue1.m_value.aULong),
                            sal::static_int_cast< unsigned long >(constValue2.m_value.aULong));
				}
				return 1;
			}
			break;
		case RT_TYPE_INT64:
			if (constValue1.m_value.aHyper != constValue2.m_value.aHyper)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
					fprintf(
                        stdout, "  Field %d: Value1 = %s  !=  Value2 = %s\n",
                        index1,
                        rtl::OUStringToOString(
                            rtl::OUString::valueOf(constValue1.m_value.aHyper),
                            RTL_TEXTENCODING_ASCII_US).getStr(),
                        rtl::OUStringToOString(
                            rtl::OUString::valueOf(constValue2.m_value.aHyper),
                            RTL_TEXTENCODING_ASCII_US).getStr());
				}
				return 1;
			}
			break;
		case RT_TYPE_UINT64:
			if (constValue1.m_value.aUHyper != constValue2.m_value.aUHyper)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
					fprintf(
                        stdout, "  Field %d: Value1 = %s  !=  Value2 = %s\n",
                        index1,
                        rtl::OUStringToOString(
                            rtl::OUString::valueOf(
                                static_cast< sal_Int64 >(
                                    constValue1.m_value.aUHyper)),
                            RTL_TEXTENCODING_ASCII_US).getStr(),
                        rtl::OUStringToOString(
                            rtl::OUString::valueOf(
                                static_cast< sal_Int64 >(
                                    constValue2.m_value.aUHyper)),
                            RTL_TEXTENCODING_ASCII_US).getStr());
                        // printing the unsigned values as signed should be
                        // acceptable...
				}
				return 1;
			}
			break;
		case RT_TYPE_FLOAT:
			if (constValue1.m_value.aFloat != constValue2.m_value.aFloat)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
                    fprintf(stdout, "  Field %d: Value1 = %f  !=  Value2 = %f\n", index1,
                            constValue1.m_value.aFloat, constValue2.m_value.aFloat);
				}
				return 1;
			}
			break;
		case RT_TYPE_DOUBLE:
			if (constValue1.m_value.aDouble != constValue2.m_value.aDouble)
			{
				if ( options.forceOutput() && !options.unoTypeCheck() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
                    fprintf(stdout, "  Field %d: Value1 = %f  !=  Value2 = %f\n", index1,
                            constValue1.m_value.aDouble, constValue2.m_value.aDouble);
				}
				return 1;
			}
			break;
        default:
            OSL_ASSERT(false);
            break;
	}	
	return 0;
}	

static sal_uInt32 checkField(Options_Impl const & options,
                             const OUString& keyName,
							 RTTypeClass typeClass,
							 sal_Bool & bDump,
							 typereg::Reader& reader1, 
							 typereg::Reader& reader2,
							 sal_uInt16 index1,
                             sal_uInt16 index2)
{
	sal_uInt32 nError = 0;
	if ( reader1.getFieldName(index1) != reader2.getFieldName(index2) )
	{
		if ( options.forceOutput() && !options.unoTypeCheck() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
            fprintf(stdout, "  Field %d: Name1 = %s  !=  Name2 = %s\n", index1,
                    U2S(reader1.getFieldName(index1)), U2S(reader2.getFieldName(index2)));
		}
		nError++;
	}
	if ( reader1.getFieldTypeName(index1) != reader2.getFieldTypeName(index2) )
	{
		if ( options.forceOutput() && !options.unoTypeCheck() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
            fprintf(stdout, "  Field %d: Type1 = %s  !=  Type2 = %s\n", index1,
                    U2S(reader1.getFieldTypeName(index1)), U2S(reader2.getFieldTypeName(index2)));
		}
		nError++;
	}
    else
	{
		RTConstValue constValue1 = reader1.getFieldValue(index1);
		RTConstValue constValue2 = reader2.getFieldValue(index2);
		if ( constValue1.m_type != constValue2.m_type )
		{
			if ( options.forceOutput() && !options.unoTypeCheck() )
			{
                dumpTypeClass (bDump, typeClass, keyName);
                fprintf(stdout, "  Field %d: Access1 = %s  !=  Access2 = %s\n", index1,
                        getConstValueType(constValue1), getConstValueType(constValue2));
                fprintf(stdout, "  Field %d: Value1 = ", index1);
                printConstValue(constValue1);
                fprintf(stdout, "  !=  Value2 = ");
                printConstValue(constValue1);
                fprintf(stdout, "\n;");
			}
			nError++;				
		}
        else
		{
			nError += checkConstValue(options, keyName, typeClass, bDump, constValue1, constValue2, index1);
		}
	}

	if ( reader1.getFieldFlags(index1) != reader2.getFieldFlags(index2) )
	{
		if ( options.forceOutput() && !options.unoTypeCheck() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
            fprintf(stdout, "  Field %d: FieldAccess1 = %s  !=  FieldAccess2 = %s\n", index1,
                    getFieldAccess(reader1.getFieldFlags(index1)).getStr(),
                    getFieldAccess(reader1.getFieldFlags(index2)).getStr());
		}
		nError++;				
	}

	if ( options.fullCheck() && (reader1.getFieldDocumentation(index1) != reader2.getFieldDocumentation(index2)) )
	{
		if ( options.forceOutput() && !options.unoTypeCheck() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
            fprintf(stdout, "  Field %d: Doku1 = %s\n             Doku2 = %s\n", index1,
                    U2S(reader1.getFieldDocumentation(index1)), U2S(reader2.getFieldDocumentation(index2)));
		}
		nError++;
	}
	return nError;
}

static char const * getMethodMode(RTMethodMode methodMode)
{
	switch ( methodMode )
	{
		case RT_MODE_ONEWAY:
			return "ONEWAY";
		case RT_MODE_ONEWAY_CONST:
			return "ONEWAY,CONST";
		case RT_MODE_TWOWAY:
			return "NONE";
		case RT_MODE_TWOWAY_CONST:
			return "CONST";
        default:
        	return "INVALID";
	}
} 

static char const * getParamMode(RTParamMode paramMode)
{
	switch ( paramMode )
	{
		case RT_PARAM_IN:
			return "IN";
		case RT_PARAM_OUT:
			return "OUT";
		case RT_PARAM_INOUT:
			return "INOUT";
        default:
        	return "INVALID";
	}
} 

static sal_uInt32 checkMethod(Options_Impl const & options,
                              const OUString& keyName,
							  RTTypeClass typeClass,
							  sal_Bool & bDump,
							  typereg::Reader& reader1, 
							  typereg::Reader& reader2,
							  sal_uInt16 index)
{
	sal_uInt32 nError = 0;
	if ( reader1.getMethodName(index) != reader2.getMethodName(index) )
	{
		if ( options.forceOutput() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  Method1 %d: Name1 = %s  !=  Name2 = %s\n", index,
					U2S(reader1.getMethodName(index)),
					U2S(reader2.getMethodName(index)));
		}
		nError++;
	}

	if ( reader1.getMethodReturnTypeName(index) != reader2.getMethodReturnTypeName(index) )
	{
		if ( options.forceOutput() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  Method1 %d: ReturnType1 = %s  !=  ReturnType2 = %s\n", index,
					U2S(reader1.getMethodReturnTypeName(index)),
					U2S(reader2.getMethodReturnTypeName(index)));
		}
		nError++;
	}

	sal_uInt16 nParams1 = (sal_uInt16)reader1.getMethodParameterCount(index);
	sal_uInt16 nParams2 = (sal_uInt16)reader2.getMethodParameterCount(index);	
	if ( nParams1 != nParams2 )
	{
		if ( options.forceOutput() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  Method %d : nParameters1 = %d  !=  nParameters2 = %d\n", index, nParams1, nParams2);
		}
		nError++;
	}
	sal_uInt16 i=0;
	for (i=0; i < nParams1 && i < nParams2; i++)
	{
		if ( reader1.getMethodParameterTypeName(index, i) != reader2.getMethodParameterTypeName(index, i) )
		{
			if ( options.forceOutput() )
			{
                dumpTypeClass (bDump, typeClass, keyName);
				fprintf(stdout, "  Method %d, Parameter %d: Type1 = %s  !=  Type2 = %s\n", index, i,
						U2S(reader1.getMethodParameterTypeName(index, i)),
						U2S(reader2.getMethodParameterTypeName(index, i)));
			}
			nError++;
		}
		if ( options.fullCheck() && (reader1.getMethodParameterName(index, i) != reader2.getMethodParameterName(index, i)) )
		{
			if ( options.forceOutput() )
			{
                dumpTypeClass (bDump, typeClass, keyName);
				fprintf(stdout, "  Method %d, Parameter %d: Name1 = %s  !=  Name2 = %s\n", index, i,
						U2S(reader1.getMethodParameterName(index, i)),
						U2S(reader2.getMethodParameterName(index, i)));
			}
			nError++;
		}
		if ( reader1.getMethodParameterFlags(index, i) != reader2.getMethodParameterFlags(index, i) )
		{
			if ( options.forceOutput() )
			{
                dumpTypeClass (bDump, typeClass, keyName);
				fprintf(stdout, "  Method %d, Parameter %d: Mode1 = %s  !=  Mode2 = %s\n", index, i,
						getParamMode(reader1.getMethodParameterFlags(index, i)),
						getParamMode(reader2.getMethodParameterFlags(index, i)));
			}
			nError++;
		}
	}
	if ( i < nParams1 && options.forceOutput() )
	{
        dumpTypeClass (bDump, typeClass, keyName);
		fprintf(stdout, "  Registry1: Method %d contains %d more parameters\n", index, nParams1 - i);
	}
	if ( i < nParams2 && options.forceOutput() )
	{
        dumpTypeClass (bDump, typeClass, keyName);
		fprintf(stdout, "  Registry2: Method %d contains %d more parameters\n", index, nParams2 - i);
	}

	sal_uInt16 nExcep1 = (sal_uInt16)reader1.getMethodExceptionCount(index);
	sal_uInt16 nExcep2 = (sal_uInt16)reader2.getMethodExceptionCount(index);	
	if ( nExcep1 != nExcep2 )
	{
		if ( options.forceOutput() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  nExceptions1 = %d  !=  nExceptions2 = %d\n", nExcep1, nExcep2);
		}
		nError++;
	}
	for (i=0; i < nExcep1 && i < nExcep2; i++)
	{
		if ( reader1.getMethodExceptionTypeName(index, i) != reader2.getMethodExceptionTypeName(index, i) )
		{
			if ( options.forceOutput() )
			{
                dumpTypeClass (bDump, typeClass, keyName);
				fprintf(stdout, "  Method %d, Exception %d: Name1 = %s  !=  Name2 = %s\n", index, i,
						U2S(reader1.getMethodExceptionTypeName(index, i)),
						U2S(reader2.getMethodExceptionTypeName(index, i)));
			}
			nError++;
		}
	}
	if ( i < nExcep1 && options.forceOutput() )
	{
        dumpTypeClass (bDump, typeClass, keyName);
		fprintf(stdout, "  Registry1: Method %d contains %d more exceptions\n", index, nExcep1 - i);
	}
	if ( i < nExcep2 && options.forceOutput() )
	{
        dumpTypeClass (bDump, typeClass, keyName);
		fprintf(stdout, "  Registry2: Method %d contains %d more exceptions\n", index, nExcep2 - i);
	}

	if ( reader1.getMethodFlags(index) != reader2.getMethodFlags(index) )
	{
		if ( options.forceOutput() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  Method %d: Mode1 = %s  !=  Mode2 = %s\n", index,
					getMethodMode(reader1.getMethodFlags(index)),
					getMethodMode(reader2.getMethodFlags(index)));
		}
		nError++;
	}

	if ( options.fullCheck() && (reader1.getMethodDocumentation(index) != reader2.getMethodDocumentation(index)) )
	{
		if ( options.forceOutput() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  Method %d: Doku1 = %s\n              Doku2 = %s\n", index,
					U2S(reader1.getMethodDocumentation(index)),
					U2S(reader2.getMethodDocumentation(index)));
		}
		nError++;
	}
	return nError;
}

static char const * getReferenceType(RTReferenceType refType)
{
	switch (refType)
	{
		case RT_REF_SUPPORTS:
			return "RT_REF_SUPPORTS";
		case RT_REF_OBSERVES:
			return "RT_REF_OBSERVES";
		case RT_REF_EXPORTS:
			return "RT_REF_EXPORTS";
		case RT_REF_NEEDS:
			return "RT_REF_NEEDS";
        default:
        	return "RT_REF_INVALID";
	}
}

static sal_uInt32 checkReference(Options_Impl const & options,
                                 const OUString& keyName,
								 RTTypeClass typeClass,
								 sal_Bool & bDump,
								 typereg::Reader& reader1,
							   	 typereg::Reader& reader2,
							   	 sal_uInt16 index1,
								 sal_uInt16 index2)
{
	sal_uInt32 nError = 0;
	if ( reader1.getReferenceTypeName(index1) != reader2.getReferenceTypeName(index2) )
	{
		if ( options.forceOutput() && !options.unoTypeCheck() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  Reference %d: Name1 = %s  !=  Name2 = %s\n", index1,
					U2S(reader1.getReferenceTypeName(index1)),
					U2S(reader2.getReferenceTypeName(index2)));
		}
		nError++;
	}
	if ( reader1.getReferenceTypeName(index1) != reader2.getReferenceTypeName(index2) )
	{
		if ( options.forceOutput() && !options.unoTypeCheck() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  Reference %d: Type1 = %s  !=  Type2 = %s\n", index1,
					getReferenceType(reader1.getReferenceSort(index1)),
					getReferenceType(reader2.getReferenceSort(index2)));
		}
		nError++;
	}
	if ( options.fullCheck() && (reader1.getReferenceDocumentation(index1) != reader2.getReferenceDocumentation(index2)) )
	{
		if ( options.forceOutput() && !options.unoTypeCheck() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  Reference %d: Doku1 = %s\n                 Doku2 = %s\n", index1,
					U2S(reader1.getReferenceDocumentation(index1)),
					U2S(reader2.getReferenceDocumentation(index2)));
		}
		nError++;
	}
	if ( reader1.getReferenceFlags(index1) != reader2.getReferenceFlags(index2) )
	{
		if ( options.forceOutput() && !options.unoTypeCheck() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
			fprintf(stdout, "  Reference %d: Access1 = %s  !=  Access2 = %s\n", index1,
					getFieldAccess(reader1.getReferenceFlags(index1)).getStr(),
					getFieldAccess(reader1.getReferenceFlags(index2)).getStr());
		}
		nError++;
	}
	return nError;
}

static sal_uInt32 checkFieldsWithoutOrder(Options_Impl const & options,
                                          const OUString& keyName,
                                          RTTypeClass typeClass,
                                          sal_Bool & bDump,
                                          typereg::Reader& reader1,
                                          typereg::Reader& reader2)
{
	sal_uInt32 nError = 0;

	sal_uInt16 nFields1 = (sal_uInt16)reader1.getFieldCount();
	sal_uInt16 nFields2 = (sal_uInt16)reader2.getFieldCount();	
    sal_uInt16 i=0, j=0;

    if ( nFields1 > nFields2 )
    {
		if ( options.forceOutput() )
		{
            dumpTypeClass (bDump, typeClass, keyName);
            fprintf(stdout, "  %s1 contains %d more properties as %s2\n",
                    getTypeClass(typeClass), nFields1-nFields2, getTypeClass(typeClass));
        }
    }

    sal_Bool bFound = sal_False;
    ::std::set< sal_uInt16 > moreProps;

    for (i=0; i < nFields1; i++)
    {
        for (j=0; j < nFields2; j++)
        {
            if (!checkField(options, keyName, typeClass, bDump, reader1, reader2, i, j))
            {
                bFound =  sal_True;
                moreProps.insert(j);
                break;
            }
        }
        if (!bFound)
        {
            if (options.forceOutput())
            {
                dumpTypeClass (bDump, typeClass, keyName);
                fprintf(stdout, "  incompatible change: Field %d ('%s') of r1 is not longer a property of this %s in r2\n",
                        i, U2S(shortName(reader1.getFieldName(i))), getTypeClass(typeClass));
            }
            nError++;
        }
        else
		{
			bFound = sal_False;
		}
    }

    if ( typeClass == RT_TYPE_SERVICE && !moreProps.empty() )
    {
        for (j=0; j < nFields2; j++)
        {
            if ( moreProps.find(j) == moreProps.end() )
            {
                if ( (reader2.getFieldFlags(j) & RT_ACCESS_OPTIONAL) != RT_ACCESS_OPTIONAL )
                {
                    if ( options.forceOutput() )
                    {
                        dumpTypeClass (bDump, typeClass, keyName);
                        fprintf(stdout,
                                "  incompatible change: Field %d ('%s') of r2 is a new property"
                                " compared to this %s in r1 and is not 'optional'\n",
                                j, U2S(shortName(reader2.getFieldName(j))), getTypeClass(typeClass));
                    }
                    nError++;
                }
            }
        }
    }
    
    return nError;
}

static sal_uInt32 checkBlob(
    Options_Impl const & options,
    const OUString& keyName,
    typereg::Reader& reader1, sal_uInt32 size1, 
    typereg::Reader& reader2, sal_uInt32 size2)
{
	sal_uInt32 nError = 0;
	sal_Bool bDump = sal_True;

	if ( options.fullCheck() && (size1 != size2) )
	{
		if ( options.forceOutput() )
		{
			fprintf(
                stdout, "    Size1 = %lu    Size2 = %lu\n",
                sal::static_int_cast< unsigned long >(size1),
                sal::static_int_cast< unsigned long >(size2));
		}
	}
    if (reader1.isPublished())
    {
        if (!reader2.isPublished())
        {
            if (options.forceOutput())
            {
                dumpTypeClass(bDump, /*"?"*/ reader1.getTypeClass(), keyName);
                fprintf(stdout, "    published in 1 but unpublished in 2\n");
            }
            ++nError;
        }
    }
    else if (!options.checkUnpublished())
    {
        return nError;
    }
	if ( reader1.getTypeClass() != reader2.getTypeClass() )
	{
		if ( options.forceOutput() )
		{
            dumpTypeClass(bDump, /*"?"*/ reader1.getTypeClass(), keyName);
			fprintf(stdout, "    TypeClass1 = %s  !=  TypeClass2 = %s\n",
					getTypeClass(reader1.getTypeClass()),
					getTypeClass(reader2.getTypeClass()));
		}
		return ++nError;
	}	

	RTTypeClass typeClass = reader1.getTypeClass();
	if ( reader1.getTypeName() != reader2.getTypeName() )
	{
		if ( options.forceOutput() )
		{
            dumpTypeClass(bDump, typeClass, keyName);
			fprintf(stdout, "    TypeName1 = %s  !=  TypeName2 = %s\n",
					U2S(reader1.getTypeName()), U2S(reader2.getTypeName()));
		}
		nError++;				
	}	
	if ( (typeClass == RT_TYPE_INTERFACE ||
		  typeClass == RT_TYPE_STRUCT ||
		  typeClass == RT_TYPE_EXCEPTION) )
	{
        if (reader1.getSuperTypeCount() != reader2.getSuperTypeCount())
        {
            dumpTypeClass(bDump, typeClass, keyName);
            fprintf(
                stdout, "    SuperTypeCount1 = %d  !=  SuperTypeCount2 = %d\n",
                static_cast< int >(reader1.getSuperTypeCount()),
                static_cast< int >(reader2.getSuperTypeCount()));
            ++nError;
        } else
        {
            for (sal_Int16 i = 0; i < reader1.getSuperTypeCount(); ++i)
            {
                if (reader1.getSuperTypeName(i) != reader2.getSuperTypeName(i))
                {
                    if ( options.forceOutput() )
                    {
                        dumpTypeClass(bDump, typeClass, keyName);
                        fprintf(stdout, "    SuperTypeName1 = %s  !=  SuperTypeName2 = %s\n",
                                U2S(reader1.getSuperTypeName(i)), U2S(reader2.getSuperTypeName(i)));
                    }
                    nError++;
                }
            }
        }
	}	

	sal_uInt16 nFields1 = (sal_uInt16)reader1.getFieldCount();
	sal_uInt16 nFields2 = (sal_uInt16)reader2.getFieldCount();	
	sal_Bool bCheckNormal = sal_True;

	if ( (typeClass == RT_TYPE_SERVICE ||
          typeClass == RT_TYPE_MODULE ||
          typeClass == RT_TYPE_CONSTANTS) && options.unoTypeCheck() )
	{
		bCheckNormal = sal_False;
	}

	if ( bCheckNormal )
	{
        if ( nFields1 != nFields2 )
        {
            if ( options.forceOutput() )
            {
                dumpTypeClass(bDump, typeClass, keyName);
                fprintf(stdout, "    nFields1 = %d  !=  nFields2 = %d\n", nFields1, nFields2);
            }
            nError++;
        }

        sal_uInt16 i;
        for (i=0; i < nFields1 && i < nFields2; i++)
        {
            nError += checkField(options, keyName, typeClass, bDump, reader1, reader2, i, i);
        }
        if ( i < nFields1 && options.forceOutput() )
        {
            dumpTypeClass(bDump, typeClass, keyName);
            fprintf(stdout, "    Registry1 contains %d more fields\n", nFields1 - i);
        }
        if ( i < nFields2 && options.forceOutput() )
        {
            dumpTypeClass(bDump, typeClass, keyName);
            fprintf(stdout, "    Registry2 contains %d more fields\n", nFields2 - i);
        }
    }
    else
    {
        nError += checkFieldsWithoutOrder(options, keyName, typeClass, bDump, reader1, reader2);
    }
        
	if ( typeClass == RT_TYPE_INTERFACE )
	{
		sal_uInt16 nMethods1 = (sal_uInt16)reader1.getMethodCount();
		sal_uInt16 nMethods2 = (sal_uInt16)reader2.getMethodCount();	
		if ( nMethods1 != nMethods2 )
		{
			if ( options.forceOutput() )
			{
                dumpTypeClass(bDump, typeClass, keyName);
				fprintf(stdout, "    nMethods1 = %d  !=  nMethods2 = %d\n", nMethods1, nMethods2);
			}
			nError++;
		}

        sal_uInt16 i;
		for (i=0; i < nMethods1 && i < nMethods2; i++)
		{
			nError += checkMethod(options, keyName, typeClass, bDump, reader1, reader2, i);
		}
		if ( i < nMethods1 && options.forceOutput() )
		{
			fprintf(stdout, "    Registry1 contains %d more methods\n", nMethods1 - i);
		}
		if ( i < nMethods2 && options.forceOutput() )
		{
			fprintf(stdout, "    Registry2 contains %d more methods\n", nMethods2 - i);
		}
	}
	if ( typeClass == RT_TYPE_SERVICE )
	{
        sal_uInt16 nReference1 = (sal_uInt16)reader1.getReferenceCount();
		sal_uInt16 nReference2 = (sal_uInt16)reader2.getReferenceCount();	

		if ( !bCheckNormal )
		{
			sal_uInt16 i=0, j=0;

			if ( nReference1 > nReference2 )
			{
				if ( options.forceOutput() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
					fprintf(stdout, "    service1 contains %d more references as service2\n",
							nReference1-nReference2);
				}
			}

			sal_Bool bFound = sal_False;
            ::std::set< sal_uInt16 > moreReferences;
            
			for (i=0; i < nReference1; i++)
			{
				for (j=0; j < nReference2; j++)
				{
					if (!checkReference(options, keyName, typeClass, bDump, reader1, reader2, i, j))
					{
						bFound =  sal_True;
                        moreReferences.insert(j);
						break;
					}
				}
				if (!bFound)
				{
					if (options.forceOutput())
					{
                        dumpTypeClass(bDump, typeClass, keyName);
						fprintf(stdout,
                                "  incompatible change: Reference %d ('%s') in 'r1' is not longer a reference"
                                " of this service in 'r2'\n", 
							    i, U2S(shortName(reader1.getReferenceTypeName(i))));
					}
					nError++;
				}
                else
				{
					bFound = sal_False;
				}
			}
            
            if ( !moreReferences.empty() )
            {
                for (j=0; j < nReference2; j++)
                {
                    if ( moreReferences.find(j) == moreReferences.end() )
                    {
                        if ( (reader2.getReferenceFlags(j) & RT_ACCESS_OPTIONAL) != RT_ACCESS_OPTIONAL )
                        {
                            if ( options.forceOutput() )
                            {
                                dumpTypeClass(bDump, typeClass, keyName);
                                fprintf(stdout,
                                        "  incompatible change: Reference %d ('%s') of r2 is a new reference"
                                        " compared to this service in r1 and is not 'optional'\n",
									    j, U2S(shortName(reader2.getReferenceTypeName(j))));
                            }
                            nError++;
                        }
                    }
                }
            }
		}
        else
		{
			if ( nReference1 != nReference2 )
			{
				if ( options.forceOutput() )
				{
                    dumpTypeClass(bDump, typeClass, keyName);
					fprintf(stdout, "    nReferences1 = %d  !=  nReferences2 = %d\n", nReference1, nReference2);
				}
				nError++;
			}

            sal_uInt16 i;
			for (i=0; i < nReference1 && i < nReference2; i++)
			{
				nError += checkReference(options, keyName, typeClass, bDump, reader1, reader2, i, i);
			}
			if ( i < nReference1 && options.forceOutput() )
			{
				fprintf(stdout, "    Registry1 contains %d more references\n", nReference1 - i);
			}
			if ( i < nReference2 && options.forceOutput() )
			{
				fprintf(stdout, "    Registry2 contains %d more references\n", nReference2 - i);
			}
		}
	}

	if ( options.fullCheck() && (reader1.getDocumentation() != reader2.getDocumentation()) )
	{
		if ( options.forceOutput() )
		{
            dumpTypeClass(bDump, typeClass, keyName);
			fprintf(stdout, "    Doku1 = %s\n    Doku2 = %s\n",
					U2S(reader1.getDocumentation()), U2S(reader2.getDocumentation()));
		}
		nError++;
	}	
	return nError;
}	

static sal_uInt32 checkValueDifference(
    Options_Impl const & options,
    RegistryKey& key1, RegValueType valueType1, sal_uInt32 size1,
    RegistryKey& key2, RegValueType valueType2, sal_uInt32 size2)
{
	OUString tmpName;
	sal_uInt32 nError = 0;

	if ( valueType1 == valueType2 )
	{
		sal_Bool bEqual = sal_True;
        switch (valueType1)
        {
        case RG_VALUETYPE_LONGLIST:
            {
				RegistryValueList<sal_Int32> valueList1;
				RegistryValueList<sal_Int32> valueList2;
				key1.getLongListValue(tmpName, valueList1);
				key2.getLongListValue(tmpName, valueList2);
				sal_uInt32 length1 = valueList1.getLength();
				sal_uInt32 length2 = valueList1.getLength();
				if ( length1 != length2 )
				{
					bEqual = sal_False;
					break;
				}
				for (sal_uInt32 i=0; i<length1; i++)
				{
					if ( valueList1.getElement(i) != valueList2.getElement(i) )
					{
						bEqual = sal_False;
						break;
					}
				}
            }
            break;
        case RG_VALUETYPE_STRINGLIST:
            {
				RegistryValueList<sal_Char*> valueList1;
				RegistryValueList<sal_Char*> valueList2;
				key1.getStringListValue(tmpName, valueList1);
				key2.getStringListValue(tmpName, valueList2);
				sal_uInt32 length1 = valueList1.getLength();
				sal_uInt32 length2 = valueList1.getLength();
				if ( length1 != length2 )
				{
					bEqual = sal_False;
					break;
				}
				for (sal_uInt32 i=0; i<length1; i++)
				{
					if ( strcmp(valueList1.getElement(i), valueList2.getElement(i)) != 0 )
					{
						bEqual = sal_False;
						break;
					}
				}
            }
            break;
        case RG_VALUETYPE_UNICODELIST:
            {
				RegistryValueList<sal_Unicode*> valueList1;
				RegistryValueList<sal_Unicode*> valueList2;
				key1.getUnicodeListValue(tmpName, valueList1);
				key2.getUnicodeListValue(tmpName, valueList2);
				sal_uInt32 length1 = valueList1.getLength();
				sal_uInt32 length2 = valueList1.getLength();
				if ( length1 != length2 )
				{
					bEqual = sal_False;
					break;
				}
				for (sal_uInt32 i=0; i<length1; i++)
				{
					if ( rtl_ustr_compare(valueList1.getElement(i), valueList2.getElement(i)) != 0 )
					{
						bEqual = sal_False;
						break;
					}
				}
            }
            break;
        default:
            break;
        }
		
		if ( bEqual)
		{
            std::vector< sal_uInt8 > value1(size1);
			key1.getValue(tmpName, &value1[0]);

            std::vector< sal_uInt8 > value2(size2);
			key2.getValue(tmpName, &value2[0]);
		
			bEqual = (rtl_compareMemory(&value1[0], &value2[0], value1.size()) == 0 );
			if ( !bEqual && valueType1 == RG_VALUETYPE_BINARY && valueType2 == RG_VALUETYPE_BINARY )
			{
                typereg::Reader reader1(&value1[0], value1.size(), false, TYPEREG_VERSION_1);
                typereg::Reader reader2(&value2[0], value2.size(), false, TYPEREG_VERSION_1);
				if ( reader1.isValid() && reader2.isValid() )
				{
					return checkBlob(options, key1.getName(), reader1, size1, reader2, size2);
				}
			}
			if ( bEqual )
			{
				return 0;
			}
            else
			{
				if ( options.forceOutput() )
				{
					fprintf(stdout, "Difference: key values of key \"%s\" are different\n", U2S(key1.getName()));
				}
				nError++;
			}
		}
	}
	
	if ( options.forceOutput() )
	{
		switch (valueType1)
		{
		case RG_VALUETYPE_NOT_DEFINED:
			fprintf(stdout, "    Registry 1: key has no value\n");
			break;
		case RG_VALUETYPE_LONG:
            {
                std::vector< sal_uInt8 > value1(size1);
                key1.getValue(tmpName, &value1[0]);

                fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_LONG\n");
                fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size1));
                fprintf(stdout, "                       Data = %p\n", &value1[0]);
            }
            break;
		case RG_VALUETYPE_STRING:
            {
                std::vector< sal_uInt8 > value1(size1);
                key1.getValue(tmpName, &value1[0]);

                fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_STRING\n");
                fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size1));
                fprintf(stdout, "                       Data = \"%s\"\n", reinterpret_cast<char const*>(&value1[0]));
            }
            break;
		case RG_VALUETYPE_UNICODE:
            {
                std::vector< sal_uInt8 > value1(size1);
                key1.getValue(tmpName, &value1[0]);

                OUString uStrValue(reinterpret_cast<sal_Unicode const*>(&value1[0]));
                fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_UNICODE\n");
                fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size1));
                fprintf(stdout, "                       Data = \"%s\"\n", U2S(uStrValue));
            }
            break;
		case RG_VALUETYPE_BINARY:
			fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_BINARY\n");
			break;
		case RG_VALUETYPE_LONGLIST:
			{
                RegistryValueList<sal_Int32> valueList;
                key1.getLongListValue(tmpName, valueList);
                fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_LONGLIST\n");
                fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size1));
                sal_uInt32 length = valueList.getLength();
                for (sal_uInt32 i=0; i<length; i++)
                {
                    fprintf(
                        stdout, "                       Data[%lu] = %ld\n",
                        sal::static_int_cast< unsigned long >(i),
                        sal::static_int_cast< long >(valueList.getElement(i)));
                }
			}
			break;
		case RG_VALUETYPE_STRINGLIST:
			{
                RegistryValueList<sal_Char*> valueList;
                key1.getStringListValue(tmpName, valueList);
                fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_STRINGLIST\n");
                fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size1));
                sal_uInt32 length = valueList.getLength();
                for (sal_uInt32 i=0; i<length; i++)
                {
                    fprintf(
                        stdout, "                       Data[%lu] = \"%s\"\n",
                        sal::static_int_cast< unsigned long >(i),
                        valueList.getElement(i));		
                }
			}
			break;
		case RG_VALUETYPE_UNICODELIST:
			{
                RegistryValueList<sal_Unicode*> valueList;
                key1.getUnicodeListValue(tmpName, valueList);
                fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_UNICODELIST\n");
                fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size1));
                sal_uInt32 length = valueList.getLength();
                OUString uStrValue;
                for (sal_uInt32 i=0; i<length; i++)
                {
                    uStrValue = OUString(valueList.getElement(i));
                    fprintf(
                        stdout, "                       Data[%lu] = \"%s\"\n",
                        sal::static_int_cast< unsigned long >(i), U2S(uStrValue));
                }
			}
			break;
		}

		switch (valueType2)
		{
		case RG_VALUETYPE_NOT_DEFINED:
			fprintf(stdout, "    Registry 2: key has no value\n");
			break;
		case RG_VALUETYPE_LONG:
            {
                std::vector< sal_uInt8 > value2(size2);
                key2.getValue(tmpName, &value2[0]);

				fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_LONG\n");
				fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size2));
				fprintf(stdout, "                       Data = %p\n", &value2[0]);
            }
            break;
		case RG_VALUETYPE_STRING:
            {
                std::vector< sal_uInt8 > value2(size2);
                key2.getValue(tmpName, &value2[0]);

				fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_STRING\n");
				fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size2));
				fprintf(stdout, "                       Data = \"%s\"\n", reinterpret_cast<char const*>(&value2[0]));
            }
            break;
		case RG_VALUETYPE_UNICODE:
            {
                std::vector< sal_uInt8 > value2(size2);
                key2.getValue(tmpName, &value2[0]);
			
				OUString uStrValue(reinterpret_cast<sal_Unicode const*>(&value2[0]));
				fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_UNICODE\n");
				fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size2));
				fprintf(stdout, "                       Data = \"%s\"\n", U2S(uStrValue));
            }
            break;
		case RG_VALUETYPE_BINARY:
			fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_BINARY\n");
			break;
		case RG_VALUETYPE_LONGLIST:
			{
                RegistryValueList<sal_Int32> valueList;
                key2.getLongListValue(tmpName, valueList);
                fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_LONGLIST\n");
                fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size2));
                sal_uInt32 length = valueList.getLength();
                for (sal_uInt32 i=0; i<length; i++)
                {
                    fprintf(
                        stdout, "                       Data[%lu] = %ld\n",
                        sal::static_int_cast< unsigned long >(i),
                        sal::static_int_cast< long >(valueList.getElement(i)));
                }
			}
			break;
		case RG_VALUETYPE_STRINGLIST:
			{
                RegistryValueList<sal_Char*> valueList;
                key2.getStringListValue(tmpName, valueList);
                fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_STRINGLIST\n");
                fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size2));
                sal_uInt32 length = valueList.getLength();
                for (sal_uInt32 i=0; i<length; i++)
                {
                    fprintf(
                        stdout, "                       Data[%lu] = \"%s\"\n",
                        sal::static_int_cast< unsigned long >(i),
                        valueList.getElement(i));		
                }
			}
			break;
		case RG_VALUETYPE_UNICODELIST:
			{
                RegistryValueList<sal_Unicode*> valueList;
                key2.getUnicodeListValue(tmpName, valueList);
                fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_UNICODELIST\n");
                fprintf(
                    stdout, "                       Size = %lu\n",
                    sal::static_int_cast< unsigned long >(size2));
                sal_uInt32 length = valueList.getLength();
                OUString uStrValue;
                for (sal_uInt32 i=0; i<length; i++)
                {
                    uStrValue = OUString(valueList.getElement(i));
                    fprintf(
                        stdout, "                       Data[%lu] = \"%s\"\n",
                        sal::static_int_cast< unsigned long >(i), U2S(uStrValue));
                }
			}
			break;
		}
	}	
	return nError;	
}	

static bool hasPublishedChildren(Options_Impl const & options, RegistryKey & key)
{
	RegistryKeyNames subKeyNames;
	key.getKeyNames(rtl::OUString(), subKeyNames);
    for (sal_uInt32 i = 0; i < subKeyNames.getLength(); ++i)
    {
        rtl::OUString keyName(subKeyNames.getElement(i));
        if (!options.matchedWithExcludeKey(keyName))
        {
            keyName = keyName.copy(keyName.lastIndexOf('/') + 1);
            RegistryKey subKey;
            if (!key.openKey(keyName, subKey))
            {
                if (options.forceOutput())
                {
                    fprintf(
                        stdout,
                        ("WARNING: could not open key \"%s\" in registry"
                         " \"%s\"\n"),
                        U2S(subKeyNames.getElement(i)),
                        options.getRegName1().c_str());
                }
            }
            if (subKey.isValid())
            {
                RegValueType type;
                sal_uInt32 size;
                if (subKey.getValueInfo(rtl::OUString(), &type, &size) != REG_NO_ERROR)
                {
                    if (options.forceOutput())
                    {
                        fprintf(
                            stdout,
                            ("WARNING: could not read key \"%s\" in registry"
                             " \"%s\"\n"),
                            U2S(subKeyNames.getElement(i)),
                            options.getRegName1().c_str());
                    }
                }
                else if (type == RG_VALUETYPE_BINARY)
                {
                    bool published = false;
                    std::vector< sal_uInt8 > value(size);
                    if (subKey.getValue(rtl::OUString(), &value[0]) != REG_NO_ERROR)
                    {
                        if (options.forceOutput())
                        {
                            fprintf(
                                stdout,
                                ("WARNING: could not read key \"%s\" in"
                                 " registry \"%s\"\n"),
                                U2S(subKeyNames.getElement(i)),
                                options.getRegName1().c_str());
                        }
                    }
                    else
                    {
                        published = typereg::Reader(&value[0], value.size(), false, TYPEREG_VERSION_1).isPublished();
                    }
                    if (published)
                    {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

static sal_uInt32 checkDifferences(
    Options_Impl const & options,
    RegistryKey& key, StringSet& keys,
    RegistryKeyNames& subKeyNames1,
    RegistryKeyNames& subKeyNames2)
{
	sal_uInt32 nError = 0;
	sal_uInt32 length1 = subKeyNames1.getLength();
	sal_uInt32 length2 = subKeyNames2.getLength();
	sal_uInt32 i,j;

	for (i=0; i<length1; i++)
	{
        sal_Bool bFound = sal_False;
		for (j=0; j<length2; j++)
		{
			if ( subKeyNames1.getElement(i) == subKeyNames2.getElement(j) )
			{
				bFound = sal_True;
				keys.insert(subKeyNames1.getElement(i));
				break;					
			}
		}
		if ( !bFound )
		{
            if ( options.fullCheck() )
            {
                if ( options.forceOutput() )
                {
                    fprintf(stdout, "EXISTENCE: key \"%s\" exists only in registry \"%s\"\n",
                            U2S(subKeyNames1.getElement(i)), options.getRegName1().c_str());
                }
                nError++;
            }
            else
            {
                rtl::OUString keyName(subKeyNames1.getElement(i));
                if (!options.matchedWithExcludeKey(keyName))
                {
                    keyName = keyName.copy(keyName.lastIndexOf('/') + 1);
                    RegistryKey subKey;
                    if (key.openKey(keyName, subKey))
                    {
                        if (options.forceOutput())
                        {
                            fprintf(
                                stdout,
                                ("ERROR: could not open key \"%s\" in registry"
                                 " \"%s\"\n"),
                                U2S(subKeyNames1.getElement(i)),
                                options.getRegName1().c_str());
                        }
                        ++nError;
                    }
                    if (subKey.isValid())
                    {
                        RegValueType type;
                        sal_uInt32 size;
                        if (subKey.getValueInfo(rtl::OUString(), &type, &size) != REG_NO_ERROR)
                        {
                            if (options.forceOutput())
                            {
                                fprintf(
                                    stdout,
                                    ("ERROR: could not read key \"%s\" in"
                                     " registry \"%s\"\n"),
                                    U2S(subKeyNames1.getElement(i)),
                                    options.getRegName1().c_str());
                            }
                            ++nError;
                        }
                        else if (type == RG_VALUETYPE_BINARY)
                        {
                            std::vector< sal_uInt8 > value(size);
                            if (subKey.getValue(rtl::OUString(), &value[0]) != REG_NO_ERROR)
                            {
                                if (options.forceOutput())
                                {
                                    fprintf(
                                        stdout,
                                        ("ERROR: could not read key \"%s\" in"
                                         " registry \"%s\"\n"),
                                        U2S(subKeyNames1.getElement(i)),
                                        options.getRegName1().c_str());
                                }
                                ++nError;
                            }
                            else
                            {
                                typereg::Reader reader(&value[0], value.size(), false, TYPEREG_VERSION_1);
                                if (reader.getTypeClass() == RT_TYPE_MODULE)
                                {
                                    if (options.checkUnpublished() || hasPublishedChildren(options, subKey))
                                    {
                                        if (options.forceOutput())
                                        {
                                            fprintf(
                                                stdout,
                                                ("EXISTENCE: module \"%s\""
                                                 " %sexists only in registry"
                                                 " 1\n"),
                                                U2S(subKeyNames1.getElement(i)),
                                                (options.checkUnpublished()
                                                 ? ""
                                                 : "with published children "));
                                        }
                                        ++nError;
                                    }
                                }
                                else if (options.checkUnpublished() || reader.isPublished())
                                {
                                    if (options.forceOutput())
                                    {
                                        fprintf(
                                            stdout,
                                            ("EXISTENCE: %spublished key \"%s\""
                                             " exists only in registry 1\n"),
                                            reader.isPublished() ? "" : "un",
                                            U2S(subKeyNames1.getElement(i)));
                                    }
                                    ++nError;
                                }
                            }
                        }
                    }
                }
            }
		}
	}

	for (i=0; i<length2; i++)
	{
        sal_Bool bFound = sal_False;
		for (j=0; j<length1; j++)
		{
			if ( subKeyNames2.getElement(i) == subKeyNames1.getElement(j) )
			{
				bFound = sal_True;
				keys.insert(subKeyNames2.getElement(i));
				break;
			}
		}
		if ( !bFound && options.fullCheck() )
		{
			if ( options.forceOutput() )
			{
				fprintf(stdout, "EXISTENCE: key \"%s\" exists only in registry \"%s\"\n",
						U2S(subKeyNames2.getElement(i)), options.getRegName2().c_str());
			}
			nError++;
		}
	}
	return nError;
}	

static sal_uInt32 compareKeys(
    Options_Impl const & options,
    RegistryKey& key1,
    RegistryKey& key2)
{
	sal_uInt32 nError = 0;
	
	RegValueType valueType1 = RG_VALUETYPE_NOT_DEFINED;
	RegValueType valueType2 = RG_VALUETYPE_NOT_DEFINED;
	sal_uInt32 size1 = 0;
	sal_uInt32 size2 = 0;

	OUString tmpName;
	RegError e1 = key1.getValueInfo(tmpName, &valueType1, &size1);
	RegError e2 = key2.getValueInfo(tmpName, &valueType2, &size2);
	if ( (e1 == e2) && (e1 != REG_VALUE_NOT_EXISTS) && (e1 != REG_INVALID_VALUE) )
	{
		nError += checkValueDifference(options, key1, valueType1, size1, key2, valueType2, size2);	
	}
    else
	{
		if ( (e1 != REG_INVALID_VALUE) || (e2 != REG_INVALID_VALUE) )
		{
			if ( options.forceOutput() )
			{
				fprintf(stdout, "VALUES: key values of key \"%s\" are different\n", U2S(key1.getName()));
			}
			nError++;
		}
	}
	
	RegistryKeyNames subKeyNames1;
	RegistryKeyNames subKeyNames2;

	key1.getKeyNames(tmpName, subKeyNames1);
	key2.getKeyNames(tmpName, subKeyNames2);

	StringSet keys;
	nError += checkDifferences(options, key1, keys, subKeyNames1, subKeyNames2);

	StringSet::iterator iter = keys.begin();
	StringSet::iterator end = keys.end();

	while ( iter !=  end )
	{
        OUString keyName(*iter);
		if ( options.matchedWithExcludeKey(keyName) )
		{
			++iter;
			continue;
		}

        sal_Int32 nPos = keyName.lastIndexOf( '/' );
        keyName = keyName.copy( nPos != -1 ? nPos+1 : 0 );

        RegistryKey subKey1;
		if ( key1.openKey(keyName, subKey1) )
		{	
			if ( options.forceOutput() )
			{
				fprintf(stdout, "ERROR: could not open key \"%s\" in registry \"%s\"\n",
						U2S(*iter), options.getRegName1().c_str());
			}
			nError++;
		}

        RegistryKey subKey2;
		if ( key2.openKey(keyName, subKey2) )
		{
			if ( options.forceOutput() )
			{
				fprintf(stdout, "ERROR: could not open key \"%s\" in registry \"%s\"\n",
						U2S(*iter), options.getRegName2().c_str());
			}
			nError++;
		}

		if ( subKey1.isValid() && subKey2.isValid() )
		{
			nError += compareKeys(options, subKey1, subKey2);
		}
		++iter;
	}

	return nError;
}	

#if (defined UNX) || (defined OS2) || defined __MINGW32__
int main( int argc, char * argv[] )
#else
int _cdecl main( int argc, char * argv[] )
#endif
{
    std::vector< std::string > args;

    Options_Impl options(argv[0]);
    for (int i = 1; i < argc; i++)
    {
        if (!Options::checkArgument(args, argv[i], strlen(argv[i])))
        {
            // failure.
            options.printUsage();
            return (1);
        }
    }
	if (!options.initOptions(args))
	{
		return (1);
	}

	OUString regName1( convertToFileUrl(options.getRegName1().c_str(), options.getRegName1().size()) );
	OUString regName2( convertToFileUrl(options.getRegName2().c_str(), options.getRegName2().size()) );
	
	Registry reg1, reg2;
	if ( reg1.open(regName1, REG_READONLY) )
	{
		fprintf(stdout, "%s: open registry \"%s\" failed\n",
				options.getProgramName().c_str(), options.getRegName1().c_str());
		return (2);
	}
	if ( reg2.open(regName2, REG_READONLY) )
	{
		fprintf(stdout, "%s: open registry \"%s\" failed\n",
				options.getProgramName().c_str(), options.getRegName2().c_str());
		return (3);
	}

	RegistryKey key1, key2;
	if ( reg1.openRootKey(key1) )
	{
		fprintf(stdout, "%s: open root key of registry \"%s\" failed\n",
				options.getProgramName().c_str(), options.getRegName1().c_str());
		return (4);
	}
	if ( reg2.openRootKey(key2) )
	{
		fprintf(stdout, "%s: open root key of registry \"%s\" failed\n",
				options.getProgramName().c_str(), options.getRegName2().c_str());
		return (5);
	}

	if ( options.isStartKeyValid() )
	{
		if ( options.matchedWithExcludeKey( options.getStartKey() ) )
		{
			fprintf(stdout, "%s: start key is equal to one of the exclude keys\n",
					options.getProgramName().c_str());
			return (6);
		}
		RegistryKey sk1, sk2;
		if ( key1.openKey(options.getStartKey(), sk1) )
		{
			fprintf(stdout, "%s: open start key of registry \"%s\" failed\n",
					options.getProgramName().c_str(), options.getRegName1().c_str());
			return (7);
		}
		if ( key2.openKey(options.getStartKey(), sk2) )
		{
			fprintf(stdout, "%s: open start key of registry \"%s\" failed\n",
					options.getProgramName().c_str(), options.getRegName2().c_str());
			return (8);
		}
		
		key1 = sk1;
		key2 = sk2;
	}
		
	sal_uInt32 nError = compareKeys(options, key1, key2);
	if ( nError )
	{
		if ( options.unoTypeCheck() )
		{
			fprintf(stdout, "%s: registries are incompatible: %lu differences!\n", 
					options.getProgramName().c_str(),
                    sal::static_int_cast< unsigned long >(nError));
		}
        else
		{
			fprintf(stdout, "%s: registries contain %lu differences!\n", 
					options.getProgramName().c_str(),
                    sal::static_int_cast< unsigned long >(nError));
		}
	}
    else
	{
		if ( options.unoTypeCheck() )
		{
			fprintf(stdout, "%s: registries are compatible!\n", 
					options.getProgramName().c_str());
		}
        else
		{
			fprintf(stdout, "%s: registries are equal!\n", 
					options.getProgramName().c_str());
		}
	}

	key1.releaseKey();
	key2.releaseKey();
	if ( reg1.close() )
	{
		fprintf(stdout, "%s: closing registry \"%s\" failed\n",
				options.getProgramName().c_str(), options.getRegName1().c_str());
        return (9);
	}
	if ( reg2.close() )
	{
		fprintf(stdout, "%s: closing registry \"%s\" failed\n",
				options.getProgramName().c_str(), options.getRegName2().c_str());
        return (10);
	}

	return ((nError > 0) ? 11 : 0);
}
