    // main.cpp SNF-SDK-WIN CPP OEM Demonstration Code
    // Copyright (C) 2009 ARM Research Labs, LLC
    //
    // This app simply exercises the API provided by snfmultidll.

    #include <iostream>
    #include <string>
    #include "../include/snfmultidll.h"

    using namespace std;

    //// Setup the basics we need to run this test.

    const string LicenseID = "licensid";                                            // SNF License ID can be passed
    const string Authentication = "authenticationxx";                               // directly or read from the
    const string ConfigurationPath = "snf_engine.xml";                              // configuration. OEMs go direct!

    const unsigned int IPToTest = 0x0c22384e;                                       // Same as IP 12.34.56.78

    const string SampleMessage =
      "Received: from mx-out.example.com [12.34.56.78] (HELO Somebody)\r\n"
      "  by mx-in.example.com (nosuchserver v1.0) for nobody@example.com\r\n"
      "From: <somebody@example.com>\r\n"
      "To: <nobody@example.com>\r\n"
      "Subject: Nothing to see here\r\n"
      "\r\n"
      "So this is the big thing that's not here to see.\r\n"
      "I thought it would be more interesting than this.\r\n"
      "\r\n"
      "_M\r\n"
      ".\r\n";

    //// Here is a simple example. Startup, exercise the API, shut down.
    //// Note that we're doing this in a very "C" style becuase the DLL API is C

    int main() {

        int Result = 0;

        Result = startupSNF(const_cast<char*>(ConfigurationPath.c_str()));

    //    Result = startupSNFAuthenticated(
    //      const_cast<char*>(ConfigurationPath.c_str()),
    //      const_cast<char*>(LicenseID.c_str()),
    //      const_cast<char*>(Authentication.c_str())
    //    );

        cout << "Started with config " << ConfigurationPath << " Result: " << Result << endl;

        // IP tests can be done asynchrounously - they do not have to be part of any particular scan.

        Result = testIP(IPToTest);
        cout << "IP test result: " << Result << endl;

        double IPReputation = getIPReputation(IPToTest);
        cout << "IP Reputation: " << IPReputation << endl;

        // Messgae scans happen in a scan, read, close cycle as shown inside this loop.

        const int NumberOfScans = 10;
        for(int i = 0; i < NumberOfScans; i++) {

            // Show how the IP reputation changes over time.

            double IPReputation = getIPReputation(IPToTest);
            cout << "IP Reputation: " << IPReputation << endl;

            // Scan a message from a buffer.

            int SetupTime = 12;
            int ScanHandle = 0;
            unsigned char* MsgBuffer = (unsigned char*) SampleMessage.c_str();
            unsigned int MsgBufferLength = (unsigned int) SampleMessage.length();
            ScanHandle = scanBuffer(MsgBuffer, MsgBufferLength, "TestMessage", SetupTime);

            cout << "Scan Handle: " << ScanHandle << endl;

            // Retrieve the X-Headers for the scan.

            char* XHeadersBuffer = 0;
            int XHeadersLength = 0;
            int ScanResult = 0;
            ScanResult = getScanXHeaders(ScanHandle, &XHeadersBuffer, &XHeadersLength);
            string XHeaders(XHeadersBuffer);

            // Close the scan.

            Result = closeScan(ScanHandle);

            cout << "Scan Close Result: " << Result << endl;

            // X- headers were captured in a string BEFORE closing the scan so we can
            // use them here.

            cout << "Scan result code: " << ScanResult << endl;
            cout << "Scan X- headers: " << XHeaders << endl;

        }

        // Now that all scanning is done we shut down.

        Result = shutdownSNF();

        return Result;

    }