You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ph...@apache.org on 2018/01/10 11:11:51 UTC

[09/19] nifi-minifi-cpp git commit: MINIFICPP-342: MQTT extension

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/epl-v10
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/epl-v10 b/thirdparty/paho.mqtt.c/epl-v10
new file mode 100644
index 0000000..79e486c
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/epl-v10
@@ -0,0 +1,70 @@
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+b) its license agreement:
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+b) a copy of this Agreement must be included with each copy of the Program.
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Los
 ses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) 
 above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/notice.html
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/notice.html b/thirdparty/paho.mqtt.c/notice.html
new file mode 100644
index 0000000..f19c483
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/notice.html
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Foundation Software User Agreement</title>
+</head>
+
+<body lang="EN-US">
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>February 1, 2011</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+   (COLLECTIVELY &quot;CONTENT&quot;).  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+   (&quot;EPL&quot;).  A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+   For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code
+   repository (&quot;Repository&quot;) in software modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p>
+
+<ul>
+       <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li>
+       <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li>
+       <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;.  Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
+      and/or Fragments associated with that Feature.</li>
+       <li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
+Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;).  Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+       <li>The top-level (root) directory</li>
+       <li>Plug-in and Fragment directories</li>
+       <li>Inside Plug-ins and Fragments packaged as JARs</li>
+       <li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li>
+       <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license (&quot;Feature Update License&quot;) during the
+installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them.  Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+       <li>Eclipse Distribution License Version 1.0 (available at <a href="http://www.eclipse.org/licenses/edl-v10.html">http://www.eclipse.org/licenses/edl-v1.0.html</a>)</li>
+       <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+       <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+       <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+       <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+       <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+
+<h3>Use of Provisioning Technology</h3>
+
+<p>The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse
+   Update Manager (&quot;Provisioning Technology&quot;) for the purpose of allowing users to install software, documentation, information and/or
+   other materials (collectively &quot;Installable Software&quot;). This capability is provided with the intent of allowing such users to
+   install, extend and update Eclipse-based products. Information about packaging Installable Software is available at <a
+       href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
+   (&quot;Specification&quot;).</p>
+
+<p>You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the
+   applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology
+   in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the
+   Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:</p>
+
+<ol>
+       <li>A series of actions may occur (&quot;Provisioning Process&quot;) in which a user may execute the Provisioning Technology
+       on a machine (&quot;Target Machine&quot;) with the intent of installing, extending or updating the functionality of an Eclipse-based
+       product.</li>
+       <li>During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be
+       accessed and copied to the Target Machine.</li>
+       <li>Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable
+       Software (&quot;Installable Software Agreement&quot;) and such Installable Software Agreement shall be accessed from the Target
+       Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern
+       the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such
+       indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.</li>
+</ol>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+   possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<p><small>Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/src/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/src/CMakeLists.txt b/thirdparty/paho.mqtt.c/src/CMakeLists.txt
new file mode 100644
index 0000000..c57185b
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/src/CMakeLists.txt
@@ -0,0 +1,165 @@
+#*******************************************************************************
+#  Copyright (c) 2015, 2017 logi.cals GmbH and others
+#
+#  All rights reserved. This program and the accompanying materials
+#  are made available under the terms of the Eclipse Public License v1.0
+#  and Eclipse Distribution License v1.0 which accompany this distribution.
+#
+#  The Eclipse Public License is available at
+#     http://www.eclipse.org/legal/epl-v10.html
+#  and the Eclipse Distribution License is available at
+#    http://www.eclipse.org/org/documents/edl-v10.php.
+#
+#  Contributors:
+#     Rainer Poisel - initial version
+#     Ian Craggs (IBM Corp.) - merge master
+#*******************************************************************************/
+
+# Note: on OS X you should install XCode and the associated command-line tools
+
+## compilation/linkage settings
+INCLUDE_DIRECTORIES(
+    .
+    ${CMAKE_BINARY_DIR}
+    )
+
+CONFIGURE_FILE(VersionInfo.h.in
+    ${CMAKE_BINARY_DIR}/VersionInfo.h
+    @ONLY
+    )
+
+SET(common_src
+    MQTTProtocolClient.c
+    Clients.c
+    utf-8.c
+    StackTrace.c
+    MQTTPacket.c
+    MQTTPacketOut.c
+    Messages.c
+    Tree.c
+    Socket.c
+    Log.c
+    MQTTPersistence.c
+    Thread.c
+    MQTTProtocolOut.c
+    MQTTPersistenceDefault.c
+    SocketBuffer.c
+    Heap.c
+    LinkedList.c
+    )
+
+IF (WIN32)
+    SET(LIBS_SYSTEM ws2_32)
+ELSEIF (UNIX)
+    IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+        SET(LIBS_SYSTEM c dl pthread)
+    ELSEIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+        SET(LIBS_SYSTEM compat pthread)
+    ELSE()
+        SET(LIBS_SYSTEM c pthread)
+    ENDIF()
+ENDIF()
+
+
+## common compilation for libpaho-mqtt3c and libpaho-mqtt3a
+ADD_LIBRARY(common_obj OBJECT ${common_src})
+SET_PROPERTY(TARGET common_obj PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+ADD_EXECUTABLE(MQTTVersion MQTTVersion.c)
+
+ADD_LIBRARY(paho-mqtt3c SHARED $<TARGET_OBJECTS:common_obj> MQTTClient.c)
+ADD_LIBRARY(paho-mqtt3a SHARED $<TARGET_OBJECTS:common_obj> MQTTAsync.c)
+
+TARGET_LINK_LIBRARIES(paho-mqtt3c ${LIBS_SYSTEM})
+TARGET_LINK_LIBRARIES(paho-mqtt3a ${LIBS_SYSTEM})
+
+TARGET_LINK_LIBRARIES(MQTTVersion paho-mqtt3a paho-mqtt3c ${LIBS_SYSTEM})
+SET_TARGET_PROPERTIES(
+    paho-mqtt3c paho-mqtt3a PROPERTIES
+    VERSION ${CLIENT_VERSION}
+    SOVERSION ${PAHO_VERSION_MAJOR})
+
+INSTALL(TARGETS paho-mqtt3c paho-mqtt3a
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+INSTALL(TARGETS MQTTVersion
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+IF (PAHO_BUILD_STATIC)
+    ADD_LIBRARY(paho-mqtt3c-static STATIC $<TARGET_OBJECTS:common_obj> MQTTClient.c)
+    ADD_LIBRARY(paho-mqtt3a-static STATIC $<TARGET_OBJECTS:common_obj> MQTTAsync.c)
+
+    TARGET_LINK_LIBRARIES(paho-mqtt3c-static ${LIBS_SYSTEM})
+    TARGET_LINK_LIBRARIES(paho-mqtt3a-static ${LIBS_SYSTEM})
+
+    INSTALL(TARGETS paho-mqtt3c-static paho-mqtt3a-static
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+ENDIF()
+
+INSTALL(FILES MQTTAsync.h MQTTClient.h MQTTClientPersistence.h
+    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+
+IF (PAHO_WITH_SSL)
+    SET(OPENSSL_SEARCH_PATH "" CACHE PATH "Directory containing OpenSSL libraries and includes")
+
+    IF (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+      SET(OPENSSL_SEARCH_PATH "/usr/local/opt/openssl")
+    ENDIF (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+
+    IF (WIN32)
+      SET(OPENSSL_SEARCH_PATH "C:/OpenSSL-Win64")
+    ENDIF ()
+
+    FIND_PATH(OPENSSL_INCLUDE_DIR openssl/ssl.h
+        HINTS ${OPENSSL_SEARCH_PATH}/include)
+    FIND_LIBRARY(OPENSSL_LIB NAMES ssl libssl ssleay32
+        HINTS ${OPENSSL_SEARCH_PATH}/lib ${OPENSSL_SEARCH_PATH}/lib64)
+    FIND_LIBRARY(OPENSSLCRYPTO_LIB NAMES crypto libcrypto libeay32
+      	HINTS ${OPENSSL_SEARCH_PATH}/lib ${OPENSSL_SEARCH_PATH}/lib64)
+
+    MESSAGE(STATUS "OpenSSL hints: ${OPENSSL_SEARCH_PATH}")
+    MESSAGE(STATUS "OpenSSL headers found at ${OPENSSL_INCLUDE_DIR}")
+    MESSAGE(STATUS "OpenSSL library found at ${OPENSSL_LIB}")
+    MESSAGE(STATUS "OpenSSL Crypto library found at ${OPENSSLCRYPTO_LIB}")
+
+    INCLUDE_DIRECTORIES(
+        ${OPENSSL_INCLUDE_DIR}
+    )
+
+    ## common compilation for libpaho-mqtt3cs and libpaho-mqtt3as
+    ## Note: SSL libraries must be recompiled due ifdefs
+    ADD_LIBRARY(common_ssl_obj OBJECT ${common_src})
+    SET_PROPERTY(TARGET common_ssl_obj PROPERTY POSITION_INDEPENDENT_CODE ON)
+    SET_PROPERTY(TARGET common_ssl_obj PROPERTY COMPILE_DEFINITIONS "OPENSSL=1")
+    ADD_LIBRARY(paho-mqtt3cs SHARED $<TARGET_OBJECTS:common_ssl_obj> MQTTClient.c SSLSocket.c)
+    ADD_LIBRARY(paho-mqtt3as SHARED $<TARGET_OBJECTS:common_ssl_obj> MQTTAsync.c SSLSocket.c)
+
+    TARGET_LINK_LIBRARIES(paho-mqtt3cs ${OPENSSL_LIB} ${OPENSSLCRYPTO_LIB} ${LIBS_SYSTEM})
+    TARGET_LINK_LIBRARIES(paho-mqtt3as ${OPENSSL_LIB} ${OPENSSLCRYPTO_LIB} ${LIBS_SYSTEM})
+    SET_TARGET_PROPERTIES(
+        paho-mqtt3cs paho-mqtt3as PROPERTIES
+        VERSION ${CLIENT_VERSION}
+        SOVERSION ${PAHO_VERSION_MAJOR}
+        COMPILE_DEFINITIONS "OPENSSL=1")
+    INSTALL(TARGETS paho-mqtt3cs paho-mqtt3as
+        ARCHIVE DESTINATION  ${CMAKE_INSTALL_LIBDIR}
+        LIBRARY DESTINATION  ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION  ${CMAKE_INSTALL_BINDIR})
+
+    IF (PAHO_BUILD_STATIC)
+        ADD_LIBRARY(paho-mqtt3cs-static STATIC $<TARGET_OBJECTS:common_ssl_obj> MQTTClient.c SSLSocket.c)
+        ADD_LIBRARY(paho-mqtt3as-static STATIC $<TARGET_OBJECTS:common_ssl_obj> MQTTAsync.c SSLSocket.c)
+
+        TARGET_LINK_LIBRARIES(paho-mqtt3cs-static ${OPENSSL_LIBRARIES} ${LIBS_SYSTEM})
+        TARGET_LINK_LIBRARIES(paho-mqtt3as-static ${OPENSSL_LIBRARIES} ${LIBS_SYSTEM})
+        SET_TARGET_PROPERTIES(
+        paho-mqtt3cs-static paho-mqtt3as-static PROPERTIES
+        VERSION ${CLIENT_VERSION}
+        SOVERSION ${PAHO_VERSION_MAJOR}
+        COMPILE_DEFINITIONS "OPENSSL=1")
+
+        INSTALL(TARGETS paho-mqtt3cs-static paho-mqtt3as-static
+            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+    ENDIF()
+ENDIF()

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/src/Clients.c
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/src/Clients.c b/thirdparty/paho.mqtt.c/src/Clients.c
new file mode 100644
index 0000000..477d248
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/src/Clients.c
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution. 
+ *
+ * The Eclipse Public License is available at 
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at 
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - add SSL support
+ *******************************************************************************/
+
+/**
+ * @file
+ * \brief functions which apply to client structures
+ * */
+
+
+#include "Clients.h"
+
+#include <string.h>
+#include <stdio.h>
+
+
+/**
+ * List callback function for comparing clients by clientid
+ * @param a first integer value
+ * @param b second integer value
+ * @return boolean indicating whether a and b are equal
+ */
+int clientIDCompare(void* a, void* b)
+{
+	Clients* client = (Clients*)a;
+	/*printf("comparing clientdIDs %s with %s\n", client->clientID, (char*)b);*/
+	return strcmp(client->clientID, (char*)b) == 0;
+}
+
+
+/**
+ * List callback function for comparing clients by socket
+ * @param a first integer value
+ * @param b second integer value
+ * @return boolean indicating whether a and b are equal
+ */
+int clientSocketCompare(void* a, void* b)
+{
+	Clients* client = (Clients*)a;
+	/*printf("comparing %d with %d\n", (char*)a, (char*)b); */
+	return client->net.socket == *(int*)b;
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/src/Clients.h
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/src/Clients.h b/thirdparty/paho.mqtt.c/src/Clients.h
new file mode 100644
index 0000000..02ed23a
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/src/Clients.h
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2017 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution. 
+ *
+ * The Eclipse Public License is available at 
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at 
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - add SSL support
+ *    Ian Craggs - fix for bug 413429 - connectionLost not called
+ *    Ian Craggs - change will payload to binary
+ *    Ian Craggs - password to binary
+ *******************************************************************************/
+
+#if !defined(CLIENTS_H)
+#define CLIENTS_H
+
+#include <time.h>
+#if defined(OPENSSL)
+#if defined(WIN32) || defined(WIN64)
+#include <winsock2.h>
+#endif
+#include <openssl/ssl.h>
+#endif
+#include "MQTTClient.h"
+#include "LinkedList.h"
+#include "MQTTClientPersistence.h"
+/*BE
+include "LinkedList"
+BE*/
+
+/*BE
+def PUBLICATIONS
+{
+   n32 ptr STRING open "topic"
+   n32 ptr DATA "payload"
+   n32 dec "payloadlen"
+   n32 dec "refcount"
+}
+BE*/
+/**
+ * Stored publication data to minimize copying
+ */
+typedef struct
+{
+	char *topic;
+	int topiclen;
+	char* payload;
+	int payloadlen;
+	int refcount;
+} Publications;
+
+/*BE
+// This should get moved to MQTTProtocol, but the includes don't quite work yet
+map MESSAGE_TYPES
+{
+   "PUBREC" 5
+   "PUBREL" .
+   "PUBCOMP" .
+}
+
+
+def MESSAGES
+{
+   n32 dec "qos"
+   n32 map bool "retain"
+   n32 dec "msgid"
+   n32 ptr PUBLICATIONS "publish"
+   n32 time "lastTouch"
+   n8 map MESSAGE_TYPES "nextMessageType"
+   n32 dec "len"
+}
+defList(MESSAGES)
+BE*/
+/**
+ * Client publication message data
+ */
+typedef struct
+{
+	int qos;
+	int retain;
+	int msgid;
+	Publications *publish;
+	time_t lastTouch;		/**> used for retry and expiry */
+	char nextMessageType;	/**> PUBREC, PUBREL, PUBCOMP */
+	int len;				/**> length of the whole structure+data */
+} Messages;
+
+
+/*BE
+def WILLMESSAGES
+{
+   n32 ptr STRING open "topic"
+   n32 ptr DATA open "msg"
+   n32 dec "retained"
+   n32 dec "qos"
+}
+BE*/
+
+/**
+ * Client will message data
+ */
+typedef struct
+{
+	char *topic;
+	int payloadlen;
+	void *payload;
+	int retained;
+	int qos;
+} willMessages;
+
+/*BE
+map CLIENT_BITS
+{
+	"cleansession" 1 : .
+	"connected" 2 : .
+	"good" 4 : .
+	"ping_outstanding" 8 : .
+}
+def CLIENTS
+{
+	n32 ptr STRING open "clientID"
+	n32 ptr STRING open "username"
+	n32 ptr STRING open "password"
+	n32 map CLIENT_BITS "bits"
+	at 4 n8 bits 7:6 dec "connect_state"
+	at 8
+	n32 dec "socket"
+	n32 ptr "SSL"
+	n32 dec "msgID"
+	n32 dec "keepAliveInterval"
+	n32 dec "maxInflightMessages"
+	n32 ptr BRIDGECONNECTIONS "bridge_context"
+	n32 time "lastContact"
+	n32 ptr WILLMESSAGES "will"
+	n32 ptr MESSAGESList open "inboundMsgs"
+	n32 ptr MESSAGESList open "outboundMsgs"
+	n32 ptr MESSAGESList open "messageQueue"
+	n32 dec "discardedMsgs"
+}
+
+defList(CLIENTS)
+
+BE*/
+
+typedef struct
+{
+	int socket;
+	time_t lastSent;
+	time_t lastReceived;
+#if defined(OPENSSL)
+	SSL* ssl;
+	SSL_CTX* ctx;
+#endif
+} networkHandles;
+
+/**
+ * Data related to one client
+ */
+typedef struct
+{
+	char* clientID;					      /**< the string id of the client */
+	const char* username;					/**< MQTT v3.1 user name */
+	int passwordlen;              /**< MQTT password length */
+	const void* password;					/**< MQTT v3.1 binary password */
+	unsigned int cleansession : 1;	/**< MQTT clean session flag */
+	unsigned int connected : 1;		/**< whether it is currently connected */
+	unsigned int good : 1; 			  /**< if we have an error on the socket we turn this off */
+	unsigned int ping_outstanding : 1;
+	int connect_state : 4;
+	networkHandles net;
+	int msgID;
+	int keepAliveInterval;
+	int retryInterval;
+	int maxInflightMessages;
+	willMessages* will;
+	List* inboundMsgs;
+	List* outboundMsgs;				/**< in flight */
+	List* messageQueue;
+	unsigned int qentry_seqno;
+	void* phandle;  /* the persistence handle */
+	MQTTClient_persistence* persistence; /* a persistence implementation */
+	void* context; /* calling context - used when calling disconnect_internal */
+	int MQTTVersion;
+#if defined(OPENSSL)
+	MQTTClient_SSLOptions *sslopts;
+	SSL_SESSION* session;    /***< SSL session pointer for fast handhake */
+#endif
+} Clients;
+
+int clientIDCompare(void* a, void* b);
+int clientSocketCompare(void* a, void* b);
+
+/**
+ * Configuration data related to all clients
+ */
+typedef struct
+{
+	const char* version;
+	List* clients;
+} ClientStates;
+
+#endif

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/src/Heap.c
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/src/Heap.c b/thirdparty/paho.mqtt.c/src/Heap.c
new file mode 100644
index 0000000..bef4c70
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/src/Heap.c
@@ -0,0 +1,481 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - use tree data structure instead of list
+ *    Ian Craggs - change roundup to Heap_roundup to avoid macro name clash on MacOSX
+ *******************************************************************************/
+
+/**
+ * @file
+ * \brief functions to manage the heap with the goal of eliminating memory leaks
+ *
+ * For any module to use these functions transparently, simply include the Heap.h
+ * header file.  Malloc and free will be redefined, but will behave in exactly the same
+ * way as normal, so no recoding is necessary.
+ *
+ * */
+
+#include "Tree.h"
+#include "Log.h"
+#include "StackTrace.h"
+#include "Thread.h"
+
+#if defined(HEAP_UNIT_TESTS)
+char* Broker_recordFFDC(char* symptoms);
+#endif /* HEAP_UNIT_TESTS */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+
+#include "Heap.h"
+
+#undef malloc
+#undef realloc
+#undef free
+
+#if defined(WIN32) || defined(WIN64)
+mutex_type heap_mutex;
+#else
+static pthread_mutex_t heap_mutex_store = PTHREAD_MUTEX_INITIALIZER;
+static mutex_type heap_mutex = &heap_mutex_store;
+#endif
+
+static heap_info state = {0, 0}; /**< global heap state information */
+static int eyecatcher = 0x88888888;
+
+/**
+ * Each item on the heap is recorded with this structure.
+ */
+typedef struct
+{
+	char* file;		/**< the name of the source file where the storage was allocated */
+	int line;		/**< the line no in the source file where it was allocated */
+	void* ptr;		/**< pointer to the allocated storage */
+	size_t size;    /**< size of the allocated storage */
+} storageElement;
+
+static Tree heap;	/**< Tree that holds the allocation records */
+static const char *errmsg = "Memory allocation error";
+
+
+static size_t Heap_roundup(size_t size);
+static int ptrCompare(void* a, void* b, int value);
+/*static void Heap_check(char* string, void* ptr);*/
+static void checkEyecatchers(char* file, int line, void* p, size_t size);
+static int Internal_heap_unlink(char* file, int line, void* p);
+static void HeapScan(enum LOG_LEVELS log_level);
+
+
+/**
+ * Round allocation size up to a multiple of the size of an int.  Apart from possibly reducing fragmentation,
+ * on the old v3 gcc compilers I was hitting some weird behaviour, which might have been errors in
+ * sizeof() used on structures and related to packing.  In any case, this fixes that too.
+ * @param size the size actually needed
+ * @return the rounded up size
+ */
+static size_t Heap_roundup(size_t size)
+{
+	static int multsize = 4*sizeof(int);
+
+	if (size % multsize != 0)
+		size += multsize - (size % multsize);
+	return size;
+}
+
+
+/**
+ * List callback function for comparing storage elements
+ * @param a pointer to the current content in the tree (storageElement*)
+ * @param b pointer to the memory to free
+ * @return boolean indicating whether a and b are equal
+ */
+static int ptrCompare(void* a, void* b, int value)
+{
+	a = ((storageElement*)a)->ptr;
+	if (value)
+		b = ((storageElement*)b)->ptr;
+
+	return (a > b) ? -1 : (a == b) ? 0 : 1;
+}
+
+/*
+static void Heap_check(char* string, void* ptr)
+{
+	Node* curnode = NULL;
+	storageElement* prev, *s = NULL;
+
+	printf("Heap_check start %p\n", ptr);
+	while ((curnode = TreeNextElement(&heap, curnode)) != NULL)
+	{
+		prev = s;
+		s = (storageElement*)(curnode->content);
+
+		if (prev)
+		{
+		if (ptrCompare(s, prev, 1) != -1)
+		{
+			printf("%s: heap order error %d %p %p\n", string, ptrCompare(s, prev, 1), prev->ptr, s->ptr);
+			exit(99);
+		}
+		else
+			printf("%s: heap order good %d %p %p\n", string, ptrCompare(s, prev, 1), prev->ptr, s->ptr);
+		}
+	}
+}*/
+
+
+/**
+ * Allocates a block of memory.  A direct replacement for malloc, but keeps track of items
+ * allocated in a list, so that free can check that a item is being freed correctly and that
+ * we can check that all memory is freed at shutdown.
+ * @param file use the __FILE__ macro to indicate which file this item was allocated in
+ * @param line use the __LINE__ macro to indicate which line this item was allocated at
+ * @param size the size of the item to be allocated
+ * @return pointer to the allocated item, or NULL if there was an error
+ */
+void* mymalloc(char* file, int line, size_t size)
+{
+	storageElement* s = NULL;
+	size_t space = sizeof(storageElement);
+	size_t filenamelen = strlen(file)+1;
+
+	Thread_lock_mutex(heap_mutex);
+	size = Heap_roundup(size);
+	if ((s = malloc(sizeof(storageElement))) == NULL)
+	{
+		Log(LOG_ERROR, 13, errmsg);
+		return NULL;
+	}
+	s->size = size; /* size without eyecatchers */
+	if ((s->file = malloc(filenamelen)) == NULL)
+	{
+		Log(LOG_ERROR, 13, errmsg);
+		free(s);
+		return NULL;
+	}
+	space += filenamelen;
+	strcpy(s->file, file);
+	s->line = line;
+	/* Add space for eyecatcher at each end */
+	if ((s->ptr = malloc(size + 2*sizeof(int))) == NULL)
+	{
+		Log(LOG_ERROR, 13, errmsg);
+		free(s->file);
+		free(s);
+		return NULL;
+	}
+	space += size + 2*sizeof(int);
+	*(int*)(s->ptr) = eyecatcher; /* start eyecatcher */
+	*(int*)(((char*)(s->ptr)) + (sizeof(int) + size)) = eyecatcher; /* end eyecatcher */
+	Log(TRACE_MAX, -1, "Allocating %d bytes in heap at file %s line %d ptr %p\n", size, file, line, s->ptr);
+	TreeAdd(&heap, s, space);
+	state.current_size += size;
+	if (state.current_size > state.max_size)
+		state.max_size = state.current_size;
+	Thread_unlock_mutex(heap_mutex);
+	return ((int*)(s->ptr)) + 1;	/* skip start eyecatcher */
+}
+
+
+static void checkEyecatchers(char* file, int line, void* p, size_t size)
+{
+	int *sp = (int*)p;
+	char *cp = (char*)p;
+	int us;
+	static const char *msg = "Invalid %s eyecatcher %d in heap item at file %s line %d";
+
+	if ((us = *--sp) != eyecatcher)
+		Log(LOG_ERROR, 13, msg, "start", us, file, line);
+
+	cp += size;
+	if ((us = *(int*)cp) != eyecatcher)
+		Log(LOG_ERROR, 13, msg, "end", us, file, line);
+}
+
+
+/**
+ * Remove an item from the recorded heap without actually freeing it.
+ * Use sparingly!
+ * @param file use the __FILE__ macro to indicate which file this item was allocated in
+ * @param line use the __LINE__ macro to indicate which line this item was allocated at
+ * @param p pointer to the item to be removed
+ */
+static int Internal_heap_unlink(char* file, int line, void* p)
+{
+	Node* e = NULL;
+	int rc = 0;
+
+	e = TreeFind(&heap, ((int*)p)-1);
+	if (e == NULL)
+		Log(LOG_ERROR, 13, "Failed to remove heap item at file %s line %d", file, line);
+	else
+	{
+		storageElement* s = (storageElement*)(e->content);
+		Log(TRACE_MAX, -1, "Freeing %d bytes in heap at file %s line %d, heap use now %d bytes\n",
+											 s->size, file, line, state.current_size);
+		checkEyecatchers(file, line, p, s->size);
+		/* free(s->ptr); */
+		free(s->file);
+		state.current_size -= s->size;
+		TreeRemoveNodeIndex(&heap, e, 0);
+		free(s);
+		rc = 1;
+	}
+	return rc;
+}
+
+
+/**
+ * Frees a block of memory.  A direct replacement for free, but checks that a item is in
+ * the allocates list first.
+ * @param file use the __FILE__ macro to indicate which file this item was allocated in
+ * @param line use the __LINE__ macro to indicate which line this item was allocated at
+ * @param p pointer to the item to be freed
+ */
+void myfree(char* file, int line, void* p)
+{
+	Thread_lock_mutex(heap_mutex);
+	if (Internal_heap_unlink(file, line, p))
+		free(((int*)p)-1);
+	Thread_unlock_mutex(heap_mutex);
+}
+
+
+/**
+ * Remove an item from the recorded heap without actually freeing it.
+ * Use sparingly!
+ * @param file use the __FILE__ macro to indicate which file this item was allocated in
+ * @param line use the __LINE__ macro to indicate which line this item was allocated at
+ * @param p pointer to the item to be removed
+ */
+void Heap_unlink(char* file, int line, void* p)
+{
+	Thread_lock_mutex(heap_mutex);
+	Internal_heap_unlink(file, line, p);
+	Thread_unlock_mutex(heap_mutex);
+}
+
+
+/**
+ * Reallocates a block of memory.  A direct replacement for realloc, but keeps track of items
+ * allocated in a list, so that free can check that a item is being freed correctly and that
+ * we can check that all memory is freed at shutdown.
+ * We have to remove the item from the tree, as the memory is in order and so it needs to
+ * be reinserted in the correct place.
+ * @param file use the __FILE__ macro to indicate which file this item was reallocated in
+ * @param line use the __LINE__ macro to indicate which line this item was reallocated at
+ * @param p pointer to the item to be reallocated
+ * @param size the new size of the item
+ * @return pointer to the allocated item, or NULL if there was an error
+ */
+void *myrealloc(char* file, int line, void* p, size_t size)
+{
+	void* rc = NULL;
+	storageElement* s = NULL;
+
+	Thread_lock_mutex(heap_mutex);
+	s = TreeRemoveKey(&heap, ((int*)p)-1);
+	if (s == NULL)
+		Log(LOG_ERROR, 13, "Failed to reallocate heap item at file %s line %d", file, line);
+	else
+	{
+		size_t space = sizeof(storageElement);
+		size_t filenamelen = strlen(file)+1;
+
+		checkEyecatchers(file, line, p, s->size);
+		size = Heap_roundup(size);
+		state.current_size += size - s->size;
+		if (state.current_size > state.max_size)
+			state.max_size = state.current_size;
+		if ((s->ptr = realloc(s->ptr, size + 2*sizeof(int))) == NULL)
+		{
+			Log(LOG_ERROR, 13, errmsg);
+			return NULL;
+		}
+		space += size + 2*sizeof(int) - s->size;
+		*(int*)(s->ptr) = eyecatcher; /* start eyecatcher */
+		*(int*)(((char*)(s->ptr)) + (sizeof(int) + size)) = eyecatcher; /* end eyecatcher */
+		s->size = size;
+		space -= strlen(s->file);
+		s->file = realloc(s->file, filenamelen);
+		space += filenamelen;
+		strcpy(s->file, file);
+		s->line = line;
+		rc = s->ptr;
+		TreeAdd(&heap, s, space);
+	}
+	Thread_unlock_mutex(heap_mutex);
+	return (rc == NULL) ? NULL : ((int*)(rc)) + 1;	/* skip start eyecatcher */
+}
+
+
+/**
+ * Utility to find an item in the heap.  Lets you know if the heap already contains
+ * the memory location in question.
+ * @param p pointer to a memory location
+ * @return pointer to the storage element if found, or NULL
+ */
+void* Heap_findItem(void* p)
+{
+	Node* e = NULL;
+
+	Thread_lock_mutex(heap_mutex);
+	e = TreeFind(&heap, ((int*)p)-1);
+	Thread_unlock_mutex(heap_mutex);
+	return (e == NULL) ? NULL : e->content;
+}
+
+
+/**
+ * Scans the heap and reports any items currently allocated.
+ * To be used at shutdown if any heap items have not been freed.
+ */
+static void HeapScan(enum LOG_LEVELS log_level)
+{
+	Node* current = NULL;
+
+	Thread_lock_mutex(heap_mutex);
+	Log(log_level, -1, "Heap scan start, total %d bytes", state.current_size);
+	while ((current = TreeNextElement(&heap, current)) != NULL)
+	{
+		storageElement* s = (storageElement*)(current->content);
+		Log(log_level, -1, "Heap element size %d, line %d, file %s, ptr %p", s->size, s->line, s->file, s->ptr);
+		Log(log_level, -1, "  Content %*.s", (10 > current->size) ? s->size : 10, (char*)(((int*)s->ptr) + 1));
+	}
+	Log(log_level, -1, "Heap scan end");
+	Thread_unlock_mutex(heap_mutex);
+}
+
+
+/**
+ * Heap initialization.
+ */
+int Heap_initialize(void)
+{
+	TreeInitializeNoMalloc(&heap, ptrCompare);
+	heap.heap_tracking = 0; /* no recursive heap tracking! */
+	return 0;
+}
+
+
+/**
+ * Heap termination.
+ */
+void Heap_terminate(void)
+{
+	Log(TRACE_MIN, -1, "Maximum heap use was %d bytes", state.max_size);
+	if (state.current_size > 20) /* One log list is freed after this function is called */
+	{
+		Log(LOG_ERROR, -1, "Some memory not freed at shutdown, possible memory leak");
+		HeapScan(LOG_ERROR);
+	}
+}
+
+
+/**
+ * Access to heap state
+ * @return pointer to the heap state structure
+ */
+heap_info* Heap_get_info(void)
+{
+	return &state;
+}
+
+
+/**
+ * Dump a string from the heap so that it can be displayed conveniently
+ * @param file file handle to dump the heap contents to
+ * @param str the string to dump, could be NULL
+ */
+int HeapDumpString(FILE* file, char* str)
+{
+	int rc = 0;
+	size_t len = str ? strlen(str) + 1 : 0; /* include the trailing null */
+
+	if (fwrite(&(str), sizeof(char*), 1, file) != 1)
+		rc = -1;
+	else if (fwrite(&(len), sizeof(int), 1 ,file) != 1)
+		rc = -1;
+	else if (len > 0 && fwrite(str, len, 1, file) != 1)
+		rc = -1;
+	return rc;
+}
+
+
+/**
+ * Dump the state of the heap
+ * @param file file handle to dump the heap contents to
+ */
+int HeapDump(FILE* file)
+{
+	int rc = 0;
+	Node* current = NULL;
+
+	while (rc == 0 && (current = TreeNextElement(&heap, current)))
+	{
+		storageElement* s = (storageElement*)(current->content);
+
+		if (fwrite(&(s->ptr), sizeof(s->ptr), 1, file) != 1)
+			rc = -1;
+		else if (fwrite(&(current->size), sizeof(current->size), 1, file) != 1)
+			rc = -1;
+		else if (fwrite(s->ptr, current->size, 1, file) != 1)
+			rc = -1;
+	}
+	return rc;
+}
+
+
+#if defined(HEAP_UNIT_TESTS)
+
+void Log(enum LOG_LEVELS log_level, int msgno, char* format, ...)
+{
+	printf("Log %s", format);
+}
+
+char* Broker_recordFFDC(char* symptoms)
+{
+	printf("recordFFDC");
+	return "";
+}
+
+#define malloc(x) mymalloc(__FILE__, __LINE__, x)
+#define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b)
+#define free(x) myfree(__FILE__, __LINE__, x)
+
+int main(int argc, char *argv[])
+{
+	char* h = NULL;
+	Heap_initialize();
+
+	h = malloc(12);
+	free(h);
+	printf("freed h\n");
+
+	h = malloc(12);
+	h = realloc(h, 14);
+	h = realloc(h, 25);
+	h = realloc(h, 255);
+	h = realloc(h, 2225);
+	h = realloc(h, 22225);
+    printf("freeing h\n");
+	free(h);
+	Heap_terminate();
+	printf("Finishing\n");
+	return 0;
+}
+
+#endif /* HEAP_UNIT_TESTS */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/src/Heap.h
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/src/Heap.h b/thirdparty/paho.mqtt.c/src/Heap.h
new file mode 100644
index 0000000..165b89f
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/src/Heap.h
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution. 
+ *
+ * The Eclipse Public License is available at 
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at 
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - use tree data structure instead of list
+ *******************************************************************************/
+
+
+#if !defined(HEAP_H)
+#define HEAP_H
+
+#if defined(HIGH_PERFORMANCE)
+#define NO_HEAP_TRACKING 1
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if !defined(NO_HEAP_TRACKING)
+/**
+ * redefines malloc to use "mymalloc" so that heap allocation can be tracked
+ * @param x the size of the item to be allocated
+ * @return the pointer to the item allocated, or NULL
+ */
+#define malloc(x) mymalloc(__FILE__, __LINE__, x)
+
+/**
+ * redefines realloc to use "myrealloc" so that heap allocation can be tracked
+ * @param a the heap item to be reallocated
+ * @param b the new size of the item
+ * @return the new pointer to the heap item
+ */
+#define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b)
+
+/**
+ * redefines free to use "myfree" so that heap allocation can be tracked
+ * @param x the size of the item to be freed
+ */
+#define free(x) myfree(__FILE__, __LINE__, x)
+
+#endif
+
+/**
+ * Information about the state of the heap.
+ */
+typedef struct
+{
+	size_t current_size;	/**< current size of the heap in bytes */
+	size_t max_size;		/**< max size the heap has reached in bytes */
+} heap_info;
+
+
+void* mymalloc(char*, int, size_t size);
+void* myrealloc(char*, int, void* p, size_t size);
+void myfree(char*, int, void* p);
+
+void Heap_scan(FILE* file);
+int Heap_initialize(void);
+void Heap_terminate(void);
+heap_info* Heap_get_info(void);
+int HeapDump(FILE* file);
+int HeapDumpString(FILE* file, char* str);
+void* Heap_findItem(void* p);
+void Heap_unlink(char* file, int line, void* p);
+
+#endif

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/src/LinkedList.c
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/src/LinkedList.c b/thirdparty/paho.mqtt.c/src/LinkedList.c
new file mode 100644
index 0000000..a8d073e
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/src/LinkedList.c
@@ -0,0 +1,500 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution. 
+ *
+ * The Eclipse Public License is available at 
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at 
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - updates for the async client
+ *******************************************************************************/
+
+/**
+ * @file
+ * \brief functions which apply to linked list structures.
+ *
+ * These linked lists can hold data of any sort, pointed to by the content pointer of the
+ * ListElement structure.  ListElements hold the points to the next and previous items in the
+ * list.
+ * */
+
+#include "LinkedList.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Heap.h"
+
+
+static int ListUnlink(List* aList, void* content, int(*callback)(void*, void*), int freeContent);
+
+
+/**
+ * Sets a list structure to empty - all null values.  Does not remove any items from the list.
+ * @param newl a pointer to the list structure to be initialized
+ */
+void ListZero(List* newl)
+{
+	memset(newl, '\0', sizeof(List));
+	/*newl->first = NULL;
+	newl->last = NULL;
+	newl->current = NULL;
+	newl->count = newl->size = 0;*/
+}
+
+
+/**
+ * Allocates and initializes a new list structure.
+ * @return a pointer to the new list structure
+ */
+List* ListInitialize(void)
+{
+	List* newl = malloc(sizeof(List));
+	ListZero(newl);
+	return newl;
+}
+
+
+/**
+ * Append an already allocated ListElement and content to a list.  Can be used to move
+ * an item from one list to another.
+ * @param aList the list to which the item is to be added
+ * @param content the list item content itself
+ * @param newel the ListElement to be used in adding the new item
+ * @param size the size of the element
+ */
+void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size)
+{ /* for heap use */
+	newel->content = content;
+	newel->next = NULL;
+	newel->prev = aList->last;
+	if (aList->first == NULL)
+		aList->first = newel;
+	else
+		aList->last->next = newel;
+	aList->last = newel;
+	++(aList->count);
+	aList->size += size;
+}
+
+
+/**
+ * Append an item to a list.
+ * @param aList the list to which the item is to be added
+ * @param content the list item content itself
+ * @param size the size of the element
+ */
+void ListAppend(List* aList, void* content, size_t size)
+{
+	ListElement* newel = malloc(sizeof(ListElement));
+	ListAppendNoMalloc(aList, content, newel, size);
+}
+
+
+/**
+ * Insert an item to a list at a specific position.
+ * @param aList the list to which the item is to be added
+ * @param content the list item content itself
+ * @param size the size of the element
+ * @param index the position in the list. If NULL, this function is equivalent
+ * to ListAppend.
+ */
+void ListInsert(List* aList, void* content, size_t size, ListElement* index)
+{
+	ListElement* newel = malloc(sizeof(ListElement));
+
+	if ( index == NULL )
+		ListAppendNoMalloc(aList, content, newel, size);
+	else
+	{
+		newel->content = content;
+		newel->next = index;
+		newel->prev = index->prev;
+
+		index->prev = newel;
+		if ( newel->prev != NULL )
+			newel->prev->next = newel;
+		else
+			aList->first = newel;
+
+		++(aList->count);
+		aList->size += size;
+	}
+}
+
+
+/**
+ * Finds an element in a list by comparing the content pointers, rather than the contents
+ * @param aList the list in which the search is to be conducted
+ * @param content pointer to the list item content itself
+ * @return the list item found, or NULL
+ */
+ListElement* ListFind(List* aList, void* content)
+{
+	return ListFindItem(aList, content, NULL);
+}
+
+
+/**
+ * Finds an element in a list by comparing the content or pointer to the content.  A callback
+ * function is used to define the method of comparison for each element.
+ * @param aList the list in which the search is to be conducted
+ * @param content pointer to the content to look for
+ * @param callback pointer to a function which compares each element (NULL means compare by content pointer)
+ * @return the list element found, or NULL
+ */
+ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*))
+{
+	ListElement* rc = NULL;
+
+	if (aList->current != NULL && ((callback == NULL && aList->current->content == content) ||
+		   (callback != NULL && callback(aList->current->content, content))))
+		rc = aList->current;
+	else
+	{
+		ListElement* current = NULL;
+
+		/* find the content */
+		while (ListNextElement(aList, &current) != NULL)
+		{
+			if (callback == NULL)
+			{
+				if (current->content == content)
+				{
+					rc = current;
+					break;
+				}
+			}
+			else
+			{
+				if (callback(current->content, content))
+				{
+					rc = current;
+					break;
+				}
+			}
+		}
+		if (rc != NULL)
+			aList->current = rc;
+	}
+	return rc;
+}
+
+
+/**
+ * Removes and optionally frees an element in a list by comparing the content.
+ * A callback function is used to define the method of comparison for each element.
+ * @param aList the list in which the search is to be conducted
+ * @param content pointer to the content to look for
+ * @param callback pointer to a function which compares each element
+ * @param freeContent boolean value to indicate whether the item found is to be freed
+ * @return 1=item removed, 0=item not removed
+ */
+static int ListUnlink(List* aList, void* content, int(*callback)(void*, void*), int freeContent)
+{
+	ListElement* next = NULL;
+	ListElement* saved = aList->current;
+	int saveddeleted = 0;
+
+	if (!ListFindItem(aList, content, callback))
+		return 0; /* false, did not remove item */
+
+	if (aList->current->prev == NULL)
+		/* so this is the first element, and we have to update the "first" pointer */
+		aList->first = aList->current->next;
+	else
+		aList->current->prev->next = aList->current->next;
+
+	if (aList->current->next == NULL)
+		aList->last = aList->current->prev;
+	else
+		aList->current->next->prev = aList->current->prev;
+
+	next = aList->current->next;
+	if (freeContent)
+		free(aList->current->content);
+	if (saved == aList->current)
+		saveddeleted = 1;
+	free(aList->current);
+	if (saveddeleted)
+		aList->current = next;
+	else
+		aList->current = saved;
+	--(aList->count);
+	return 1; /* successfully removed item */
+}
+
+
+/**
+ * Removes but does not free an item in a list by comparing the pointer to the content.
+ * @param aList the list in which the search is to be conducted
+ * @param content pointer to the content to look for
+ * @return 1=item removed, 0=item not removed
+ */
+int ListDetach(List* aList, void* content)
+{
+	return ListUnlink(aList, content, NULL, 0);
+}
+
+
+/**
+ * Removes and frees an item in a list by comparing the pointer to the content.
+ * @param aList the list from which the item is to be removed
+ * @param content pointer to the content to look for
+ * @return 1=item removed, 0=item not removed
+ */
+int ListRemove(List* aList, void* content)
+{
+	return ListUnlink(aList, content, NULL, 1);
+}
+
+
+/**
+ * Removes and frees an the first item in a list.
+ * @param aList the list from which the item is to be removed
+ * @return 1=item removed, 0=item not removed
+ */
+void* ListDetachHead(List* aList)
+{
+	void *content = NULL;
+	if (aList->count > 0)
+	{
+		ListElement* first = aList->first;
+		if (aList->current == first)
+			aList->current = first->next;
+		if (aList->last == first) /* i.e. no of items in list == 1 */
+			aList->last = NULL;
+		content = first->content;
+		aList->first = aList->first->next;
+		if (aList->first)
+			aList->first->prev = NULL;
+		free(first);
+		--(aList->count);
+	}
+	return content;
+}
+
+
+/**
+ * Removes and frees an the first item in a list.
+ * @param aList the list from which the item is to be removed
+ * @return 1=item removed, 0=item not removed
+ */
+int ListRemoveHead(List* aList)
+{
+	free(ListDetachHead(aList));
+	return 0;
+}
+
+
+/**
+ * Removes but does not free the last item in a list.
+ * @param aList the list from which the item is to be removed
+ * @return the last item removed (or NULL if none was)
+ */
+void* ListPopTail(List* aList)
+{
+	void* content = NULL;
+	if (aList->count > 0)
+	{
+		ListElement* last = aList->last;
+		if (aList->current == last)
+			aList->current = last->prev;
+		if (aList->first == last) /* i.e. no of items in list == 1 */
+			aList->first = NULL;
+		content = last->content;
+		aList->last = aList->last->prev;
+		if (aList->last)
+			aList->last->next = NULL;
+		free(last);
+		--(aList->count);
+	}
+	return content;
+}
+
+
+/**
+ * Removes but does not free an element in a list by comparing the content.
+ * A callback function is used to define the method of comparison for each element.
+ * @param aList the list in which the search is to be conducted
+ * @param content pointer to the content to look for
+ * @param callback pointer to a function which compares each element
+ * @return 1=item removed, 0=item not removed
+ */
+int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*))
+{ /* do not free the content */
+	return ListUnlink(aList, content, callback, 0);
+}
+
+
+/**
+ * Removes and frees an element in a list by comparing the content.
+ * A callback function is used to define the method of comparison for each element
+ * @param aList the list in which the search is to be conducted
+ * @param content pointer to the content to look for
+ * @param callback pointer to a function which compares each element
+ * @return 1=item removed, 0=item not removed
+ */
+int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*))
+{ /* remove from list and free the content */
+	return ListUnlink(aList, content, callback, 1);
+}
+
+
+/**
+ * Removes and frees all items in a list, leaving the list ready for new items.
+ * @param aList the list to which the operation is to be applied
+ */
+void ListEmpty(List* aList)
+{
+	while (aList->first != NULL)
+	{
+		ListElement* first = aList->first;
+		if (first->content != NULL)
+			free(first->content);
+		aList->first = first->next;
+		free(first);
+	}
+	aList->count = 0;
+	aList->size = 0;
+	aList->current = aList->first = aList->last = NULL;
+}
+
+/**
+ * Removes and frees all items in a list, and frees the list itself
+ * @param aList the list to which the operation is to be applied
+ */
+void ListFree(List* aList)
+{
+	ListEmpty(aList);
+	free(aList);
+}
+
+
+/**
+ * Removes and but does not free all items in a list, and frees the list itself
+ * @param aList the list to which the operation is to be applied
+ */
+void ListFreeNoContent(List* aList)
+{
+	while (aList->first != NULL)
+	{
+		ListElement* first = aList->first;
+		aList->first = first->next;
+		free(first);
+	}
+	free(aList);
+}
+
+
+/**
+ * Forward iteration through a list
+ * @param aList the list to which the operation is to be applied
+ * @param pos pointer to the current position in the list.  NULL means start from the beginning of the list
+ * This is updated on return to the same value as that returned from this function
+ * @return pointer to the current list element
+ */
+ListElement* ListNextElement(List* aList, ListElement** pos)
+{
+	return *pos = (*pos == NULL) ? aList->first : (*pos)->next;
+}
+
+
+/**
+ * Backward iteration through a list
+ * @param aList the list to which the operation is to be applied
+ * @param pos pointer to the current position in the list.  NULL means start from the end of the list
+ * This is updated on return to the same value as that returned from this function
+ * @return pointer to the current list element
+ */
+ListElement* ListPrevElement(List* aList, ListElement** pos)
+{
+	return *pos = (*pos == NULL) ? aList->last : (*pos)->prev;
+}
+
+
+/**
+ * List callback function for comparing integers
+ * @param a first integer value
+ * @param b second integer value
+ * @return boolean indicating whether a and b are equal
+ */
+int intcompare(void* a, void* b)
+{
+	return *((int*)a) == *((int*)b);
+}
+
+
+/**
+ * List callback function for comparing C strings
+ * @param a first integer value
+ * @param b second integer value
+ * @return boolean indicating whether a and b are equal
+ */
+int stringcompare(void* a, void* b)
+{
+	return strcmp((char*)a, (char*)b) == 0;
+}
+
+
+#if defined(UNIT_TESTS)
+
+
+int main(int argc, char *argv[])
+{
+	int i, *ip, *todelete;
+	ListElement* current = NULL;
+	List* l = ListInitialize();
+	printf("List initialized\n");
+
+	for (i = 0; i < 10; i++)
+	{
+		ip = malloc(sizeof(int));
+		*ip = i;
+		ListAppend(l, (void*)ip, sizeof(int));
+		if (i==5)
+			todelete = ip;
+		printf("List element appended %d\n",  *((int*)(l->last->content)));
+	}
+
+	printf("List contents:\n");
+	current = NULL;
+	while (ListNextElement(l, &current) != NULL)
+		printf("List element: %d\n", *((int*)(current->content)));
+
+	printf("List contents in reverse order:\n");
+	current = NULL;
+	while (ListPrevElement(l, &current) != NULL)
+		printf("List element: %d\n", *((int*)(current->content)));
+
+	/* if ListFindItem(l, *ip, intcompare)->content */
+
+	printf("List contents having deleted element %d:\n", *todelete);
+	ListRemove(l, todelete);
+	current = NULL;
+	while (ListNextElement(l, &current) != NULL)
+		printf("List element: %d\n", *((int*)(current->content)));
+
+	i = 9;
+	ListRemoveItem(l, &i, intcompare);
+	printf("List contents having deleted another element, %d, size now %d:\n", i, l->size);
+	current = NULL;
+	while (ListNextElement(l, &current) != NULL)
+		printf("List element: %d\n", *((int*)(current->content)));
+
+	ListFree(l);
+	printf("List freed\n");
+}
+
+#endif
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/src/LinkedList.h
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/src/LinkedList.h b/thirdparty/paho.mqtt.c/src/LinkedList.h
new file mode 100644
index 0000000..102a4fd
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/src/LinkedList.h
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution. 
+ *
+ * The Eclipse Public License is available at 
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at 
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - updates for the async client
+ *    Ian Craggs - change size types from int to size_t
+ *******************************************************************************/
+
+#if !defined(LINKEDLIST_H)
+#define LINKEDLIST_H
+
+#include <stdlib.h> /* for size_t definition */
+
+/*BE
+defm defList(T)
+
+def T concat Item
+{
+	at 4
+	n32 ptr T concat Item suppress "next"
+	at 0
+	n32 ptr T concat Item suppress "prev"
+	at 8
+	n32 ptr T id2str(T)
+}
+
+def T concat List
+{
+	n32 ptr T concat Item suppress "first"
+	n32 ptr T concat Item suppress "last"
+	n32 ptr T concat Item suppress "current"
+	n32 dec "count"
+	n32 suppress "size"
+}
+endm
+
+defList(INT)
+defList(STRING)
+defList(TMP)
+
+BE*/
+
+/**
+ * Structure to hold all data for one list element
+ */
+typedef struct ListElementStruct
+{
+	struct ListElementStruct *prev, /**< pointer to previous list element */
+							*next;	/**< pointer to next list element */
+	void* content;					/**< pointer to element content */
+} ListElement;
+
+
+/**
+ * Structure to hold all data for one list
+ */
+typedef struct
+{
+	ListElement *first,	/**< first element in the list */
+				*last,	/**< last element in the list */
+				*current;	/**< current element in the list, for iteration */
+	int count;  /**< no of items */
+	size_t size;  /**< heap storage used */
+} List;
+
+void ListZero(List*);
+List* ListInitialize(void);
+
+void ListAppend(List* aList, void* content, size_t size);
+void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size);
+void ListInsert(List* aList, void* content, size_t size, ListElement* index);
+
+int ListRemove(List* aList, void* content);
+int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*));
+void* ListDetachHead(List* aList);
+int ListRemoveHead(List* aList);
+void* ListPopTail(List* aList);
+
+int ListDetach(List* aList, void* content);
+int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*));
+
+void ListFree(List* aList);
+void ListEmpty(List* aList);
+void ListFreeNoContent(List* aList);
+
+ListElement* ListNextElement(List* aList, ListElement** pos);
+ListElement* ListPrevElement(List* aList, ListElement** pos);
+
+ListElement* ListFind(List* aList, void* content);
+ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*));
+
+int intcompare(void* a, void* b);
+int stringcompare(void* a, void* b);
+
+#endif

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/src/Log.c
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/src/Log.c b/thirdparty/paho.mqtt.c/src/Log.c
new file mode 100644
index 0000000..472e888
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/src/Log.c
@@ -0,0 +1,572 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution. 
+ *
+ * The Eclipse Public License is available at 
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at 
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - updates for the async client
+ *    Ian Craggs - fix for bug #427028
+ *******************************************************************************/
+
+/**
+ * @file
+ * \brief Logging and tracing module
+ *
+ * 
+ */
+
+#include "Log.h"
+#include "MQTTPacket.h"
+#include "MQTTProtocol.h"
+#include "MQTTProtocolClient.h"
+#include "Messages.h"
+#include "LinkedList.h"
+#include "StackTrace.h"
+#include "Thread.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <time.h>
+#include <string.h>
+
+#if !defined(WIN32) && !defined(WIN64)
+#include <syslog.h>
+#include <sys/stat.h>
+#define GETTIMEOFDAY 1
+#else
+#define snprintf _snprintf
+#endif
+
+#if defined(GETTIMEOFDAY)
+	#include <sys/time.h>
+#else
+	#include <sys/timeb.h>
+#endif
+
+#if !defined(WIN32) && !defined(WIN64)
+/**
+ * _unlink mapping for linux
+ */
+#define _unlink unlink
+#endif
+
+
+#if !defined(min)
+#define min(A,B) ( (A) < (B) ? (A):(B))
+#endif
+
+trace_settings_type trace_settings =
+{
+	TRACE_MINIMUM,
+	400,
+	INVALID_LEVEL
+};
+
+#define MAX_FUNCTION_NAME_LENGTH 256
+
+typedef struct
+{
+#if defined(GETTIMEOFDAY)
+	struct timeval ts;
+#else
+	struct timeb ts;
+#endif
+	int sametime_count;
+	int number;
+	int thread_id;
+	int depth;
+	char name[MAX_FUNCTION_NAME_LENGTH + 1];
+	int line;
+	int has_rc;
+	int rc;
+	enum LOG_LEVELS level;
+} traceEntry;
+
+static int start_index = -1,
+			next_index = 0;
+static traceEntry* trace_queue = NULL;
+static int trace_queue_size = 0;
+
+static FILE* trace_destination = NULL;	/**< flag to indicate if trace is to be sent to a stream */
+static char* trace_destination_name = NULL; /**< the name of the trace file */
+static char* trace_destination_backup_name = NULL; /**< the name of the backup trace file */
+static int lines_written = 0; /**< number of lines written to the current output file */
+static int max_lines_per_file = 1000; /**< maximum number of lines to write to one trace file */
+static enum LOG_LEVELS trace_output_level = INVALID_LEVEL;
+static Log_traceCallback* trace_callback = NULL;
+static traceEntry* Log_pretrace(void);
+static char* Log_formatTraceEntry(traceEntry* cur_entry);
+static void Log_output(enum LOG_LEVELS log_level, const char *msg);
+static void Log_posttrace(enum LOG_LEVELS log_level, traceEntry* cur_entry);
+static void Log_trace(enum LOG_LEVELS log_level, const char *buf);
+#if 0
+static FILE* Log_destToFile(const char *dest);
+static int Log_compareEntries(const char *entry1, const char *entry2);
+#endif
+
+static int sametime_count = 0;
+#if defined(GETTIMEOFDAY)
+struct timeval ts, last_ts;
+#else
+struct timeb ts, last_ts;
+#endif
+static char msg_buf[512];
+
+#if defined(WIN32) || defined(WIN64)
+mutex_type log_mutex;
+#else
+static pthread_mutex_t log_mutex_store = PTHREAD_MUTEX_INITIALIZER;
+static mutex_type log_mutex = &log_mutex_store;
+#endif
+
+
+int Log_initialize(Log_nameValue* info)
+{
+	int rc = -1;
+	char* envval = NULL;
+
+	if ((trace_queue = malloc(sizeof(traceEntry) * trace_settings.max_trace_entries)) == NULL)
+		return rc;
+	trace_queue_size = trace_settings.max_trace_entries;
+
+	if ((envval = getenv("MQTT_C_CLIENT_TRACE")) != NULL && strlen(envval) > 0)
+	{
+		if (strcmp(envval, "ON") == 0 || (trace_destination = fopen(envval, "w")) == NULL)
+			trace_destination = stdout;
+		else
+		{
+			trace_destination_name = malloc(strlen(envval) + 1);
+			strcpy(trace_destination_name, envval);
+			trace_destination_backup_name = malloc(strlen(envval) + 3);
+			sprintf(trace_destination_backup_name, "%s.0", trace_destination_name);
+		}
+	}
+	if ((envval = getenv("MQTT_C_CLIENT_TRACE_MAX_LINES")) != NULL && strlen(envval) > 0)
+	{
+		max_lines_per_file = atoi(envval);
+		if (max_lines_per_file <= 0)
+			max_lines_per_file = 1000;
+	}
+	if ((envval = getenv("MQTT_C_CLIENT_TRACE_LEVEL")) != NULL && strlen(envval) > 0)
+	{
+		if (strcmp(envval, "MAXIMUM") == 0 || strcmp(envval, "TRACE_MAXIMUM") == 0)
+			trace_settings.trace_level = TRACE_MAXIMUM;
+		else if (strcmp(envval, "MEDIUM") == 0 || strcmp(envval, "TRACE_MEDIUM") == 0)
+			trace_settings.trace_level = TRACE_MEDIUM;
+		else if (strcmp(envval, "MINIMUM") == 0 || strcmp(envval, "TRACE_MEDIUM") == 0)
+			trace_settings.trace_level = TRACE_MINIMUM;
+		else if (strcmp(envval, "PROTOCOL") == 0  || strcmp(envval, "TRACE_PROTOCOL") == 0)
+			trace_output_level = TRACE_PROTOCOL;
+		else if (strcmp(envval, "ERROR") == 0  || strcmp(envval, "TRACE_ERROR") == 0)
+			trace_output_level = LOG_ERROR;
+	}
+	Log_output(TRACE_MINIMUM, "=========================================================");
+	Log_output(TRACE_MINIMUM, "                   Trace Output");
+	if (info)
+	{
+		while (info->name)
+		{
+			snprintf(msg_buf, sizeof(msg_buf), "%s: %s", info->name, info->value);
+			Log_output(TRACE_MINIMUM, msg_buf);
+			info++;
+		}
+	}
+#if !defined(WIN32) && !defined(WIN64)
+	struct stat buf;
+	if (stat("/proc/version", &buf) != -1)
+	{
+		FILE* vfile;
+		
+		if ((vfile = fopen("/proc/version", "r")) != NULL)
+		{
+			int len;
+			
+			strcpy(msg_buf, "/proc/version: ");
+			len = strlen(msg_buf);
+			if (fgets(&msg_buf[len], sizeof(msg_buf) - len, vfile))
+				Log_output(TRACE_MINIMUM, msg_buf);
+			fclose(vfile);
+		}
+	}
+#endif
+	Log_output(TRACE_MINIMUM, "=========================================================");
+		
+	return rc;
+}
+
+
+void Log_setTraceCallback(Log_traceCallback* callback)
+{
+	trace_callback = callback;
+}
+
+
+void Log_setTraceLevel(enum LOG_LEVELS level)
+{
+	if (level < TRACE_MINIMUM) /* the lowest we can go is TRACE_MINIMUM*/
+		trace_settings.trace_level = level;
+	trace_output_level = level;
+}
+
+
+void Log_terminate(void)
+{
+	free(trace_queue);
+	trace_queue = NULL;
+	trace_queue_size = 0;
+	if (trace_destination)
+	{
+		if (trace_destination != stdout)
+			fclose(trace_destination);
+		trace_destination = NULL;
+	}
+	if (trace_destination_name) {
+		free(trace_destination_name);
+		trace_destination_name = NULL;
+	}
+	if (trace_destination_backup_name) {
+		free(trace_destination_backup_name);
+		trace_destination_backup_name = NULL;
+	}
+	start_index = -1;
+	next_index = 0;
+	trace_output_level = INVALID_LEVEL;
+	sametime_count = 0;
+}
+
+
+static traceEntry* Log_pretrace(void)
+{
+	traceEntry *cur_entry = NULL;
+
+	/* calling ftime/gettimeofday seems to be comparatively expensive, so we need to limit its use */
+	if (++sametime_count % 20 == 0)
+	{
+#if defined(GETTIMEOFDAY)
+		gettimeofday(&ts, NULL);
+		if (ts.tv_sec != last_ts.tv_sec || ts.tv_usec != last_ts.tv_usec)
+#else
+		ftime(&ts);
+		if (ts.time != last_ts.time || ts.millitm != last_ts.millitm)
+#endif
+		{
+			sametime_count = 0;
+			last_ts = ts;
+		}
+	}
+
+	if (trace_queue_size != trace_settings.max_trace_entries)
+	{
+		traceEntry* new_trace_queue = malloc(sizeof(traceEntry) * trace_settings.max_trace_entries);
+
+		memcpy(new_trace_queue, trace_queue, min(trace_queue_size, trace_settings.max_trace_entries) * sizeof(traceEntry));
+		free(trace_queue);
+		trace_queue = new_trace_queue;
+		trace_queue_size = trace_settings.max_trace_entries;
+
+		if (start_index > trace_settings.max_trace_entries + 1 ||
+				next_index > trace_settings.max_trace_entries + 1)
+		{
+			start_index = -1;
+			next_index = 0;
+		}
+	}
+
+	/* add to trace buffer */
+	cur_entry = &trace_queue[next_index];
+	if (next_index == start_index) /* means the buffer is full */
+	{
+		if (++start_index == trace_settings.max_trace_entries)
+			start_index = 0;
+	} else if (start_index == -1)
+		start_index = 0;
+	if (++next_index == trace_settings.max_trace_entries)
+		next_index = 0;
+
+	return cur_entry;
+}
+
+static char* Log_formatTraceEntry(traceEntry* cur_entry)
+{
+	struct tm *timeinfo;
+	int buf_pos = 31;
+
+#if defined(GETTIMEOFDAY)
+	timeinfo = localtime((time_t *)&cur_entry->ts.tv_sec);
+#else
+	timeinfo = localtime(&cur_entry->ts.time);
+#endif
+	strftime(&msg_buf[7], 80, "%Y%m%d %H%M%S ", timeinfo);
+#if defined(GETTIMEOFDAY)
+	sprintf(&msg_buf[22], ".%.3lu ", cur_entry->ts.tv_usec / 1000L);
+#else
+	sprintf(&msg_buf[22], ".%.3hu ", cur_entry->ts.millitm);
+#endif
+	buf_pos = 27;
+
+	sprintf(msg_buf, "(%.4d)", cur_entry->sametime_count);
+	msg_buf[6] = ' ';
+
+	if (cur_entry->has_rc == 2)
+		strncpy(&msg_buf[buf_pos], cur_entry->name, sizeof(msg_buf)-buf_pos);
+	else
+	{
+		const char *format = Messages_get(cur_entry->number, cur_entry->level);
+		if (cur_entry->has_rc == 1)
+			snprintf(&msg_buf[buf_pos], sizeof(msg_buf)-buf_pos, format, cur_entry->thread_id,
+					cur_entry->depth, "", cur_entry->depth, cur_entry->name, cur_entry->line, cur_entry->rc);
+		else
+			snprintf(&msg_buf[buf_pos], sizeof(msg_buf)-buf_pos, format, cur_entry->thread_id,
+					cur_entry->depth, "", cur_entry->depth, cur_entry->name, cur_entry->line);
+	}
+	return msg_buf;
+}
+
+
+static void Log_output(enum LOG_LEVELS log_level, const char *msg)
+{
+	if (trace_destination)
+	{
+		fprintf(trace_destination, "%s\n", msg);
+
+		if (trace_destination != stdout && ++lines_written >= max_lines_per_file)
+		{	
+
+			fclose(trace_destination);		
+			_unlink(trace_destination_backup_name); /* remove any old backup trace file */
+			rename(trace_destination_name, trace_destination_backup_name); /* rename recently closed to backup */
+			trace_destination = fopen(trace_destination_name, "w"); /* open new trace file */
+			if (trace_destination == NULL)
+				trace_destination = stdout;
+			lines_written = 0;
+		}
+		else
+			fflush(trace_destination);
+	}
+		
+	if (trace_callback)
+		(*trace_callback)(log_level, msg);
+}
+
+
+static void Log_posttrace(enum LOG_LEVELS log_level, traceEntry* cur_entry)
+{
+	if (((trace_output_level == -1) ? log_level >= trace_settings.trace_level : log_level >= trace_output_level))
+	{
+		char* msg = NULL;
+		
+		if (trace_destination || trace_callback)
+			msg = &Log_formatTraceEntry(cur_entry)[7];
+		
+		Log_output(log_level, msg);
+	}
+}
+
+
+static void Log_trace(enum LOG_LEVELS log_level, const char *buf)
+{
+	traceEntry *cur_entry = NULL;
+
+	if (trace_queue == NULL)
+		return;
+
+	cur_entry = Log_pretrace();
+
+	memcpy(&(cur_entry->ts), &ts, sizeof(ts));
+	cur_entry->sametime_count = sametime_count;
+
+	cur_entry->has_rc = 2;
+	strncpy(cur_entry->name, buf, sizeof(cur_entry->name));
+	cur_entry->name[MAX_FUNCTION_NAME_LENGTH] = '\0';
+
+	Log_posttrace(log_level, cur_entry);
+}
+
+
+/**
+ * Log a message.  If possible, all messages should be indexed by message number, and
+ * the use of the format string should be minimized or negated altogether.  If format is
+ * provided, the message number is only used as a message label.
+ * @param log_level the log level of the message
+ * @param msgno the id of the message to use if the format string is NULL
+ * @param aFormat the printf format string to be used if the message id does not exist
+ * @param ... the printf inserts
+ */
+void Log(enum LOG_LEVELS log_level, int msgno, const char *format, ...)
+{
+	if (log_level >= trace_settings.trace_level)
+	{
+		const char *temp = NULL;
+		static char msg_buf[512];
+		va_list args;
+
+		/* we're using a static character buffer, so we need to make sure only one thread uses it at a time */
+		Thread_lock_mutex(log_mutex); 
+		if (format == NULL && (temp = Messages_get(msgno, log_level)) != NULL)
+			format = temp;
+
+		va_start(args, format);
+		vsnprintf(msg_buf, sizeof(msg_buf), format, args);
+
+		Log_trace(log_level, msg_buf);
+		va_end(args);
+		Thread_unlock_mutex(log_mutex); 
+	}
+
+	/*if (log_level >= LOG_ERROR)
+	{
+		char* filename = NULL;
+		Log_recordFFDC(&msg_buf[7]);
+	}
+	*/
+}
+
+
+/**
+ * The reason for this function is to make trace logging as fast as possible so that the
+ * function exit/entry history can be captured by default without unduly impacting
+ * performance.  Therefore it must do as little as possible.
+ * @param log_level the log level of the message
+ * @param msgno the id of the message to use if the format string is NULL
+ * @param aFormat the printf format string to be used if the message id does not exist
+ * @param ... the printf inserts
+ */
+void Log_stackTrace(enum LOG_LEVELS log_level, int msgno, int thread_id, int current_depth, const char* name, int line, int* rc)
+{
+	traceEntry *cur_entry = NULL;
+
+	if (trace_queue == NULL)
+		return;
+
+	if (log_level < trace_settings.trace_level)
+		return;
+
+	Thread_lock_mutex(log_mutex);
+	cur_entry = Log_pretrace();
+
+	memcpy(&(cur_entry->ts), &ts, sizeof(ts));
+	cur_entry->sametime_count = sametime_count;
+	cur_entry->number = msgno;
+	cur_entry->thread_id = thread_id;
+	cur_entry->depth = current_depth;
+	strcpy(cur_entry->name, name);
+	cur_entry->level = log_level;
+	cur_entry->line = line;
+	if (rc == NULL)
+		cur_entry->has_rc = 0;
+	else
+	{
+		cur_entry->has_rc = 1;
+		cur_entry->rc = *rc;
+	}
+
+	Log_posttrace(log_level, cur_entry);
+	Thread_unlock_mutex(log_mutex);
+}
+
+
+#if 0
+static FILE* Log_destToFile(const char *dest)
+{
+	FILE* file = NULL;
+
+	if (strcmp(dest, "stdout") == 0)
+		file = stdout;
+	else if (strcmp(dest, "stderr") == 0)
+		file = stderr;
+	else
+	{
+		if (strstr(dest, "FFDC"))
+			file = fopen(dest, "ab");
+		else
+			file = fopen(dest, "wb");
+	}
+	return file;
+}
+
+
+static int Log_compareEntries(const char *entry1, const char *entry2)
+{
+	int comp = strncmp(&entry1[7], &entry2[7], 19);
+
+	/* if timestamps are equal, use the sequence numbers */
+	if (comp == 0)
+		comp = strncmp(&entry1[1], &entry2[1], 4);
+
+	return comp;
+}
+
+
+/**
+ * Write the contents of the stored trace to a stream
+ * @param dest string which contains a file name or the special strings stdout or stderr
+ */
+int Log_dumpTrace(char* dest)
+{
+	FILE* file = NULL;
+	ListElement* cur_trace_entry = NULL;
+	const int msgstart = 7;
+	int rc = -1;
+	int trace_queue_index = 0;
+
+	if ((file = Log_destToFile(dest)) == NULL)
+	{
+		Log(LOG_ERROR, 9, NULL, "trace", dest, "trace entries");
+		goto exit;
+	}
+
+	fprintf(file, "=========== Start of trace dump ==========\n");
+	/* Interleave the log and trace entries together appropriately */
+	ListNextElement(trace_buffer, &cur_trace_entry);
+	trace_queue_index = start_index;
+	if (trace_queue_index == -1)
+		trace_queue_index = next_index;
+	else
+	{
+		Log_formatTraceEntry(&trace_queue[trace_queue_index++]);
+		if (trace_queue_index == trace_settings.max_trace_entries)
+			trace_queue_index = 0;
+	}
+	while (cur_trace_entry || trace_queue_index != next_index)
+	{
+		if (cur_trace_entry && trace_queue_index != -1)
+		{	/* compare these timestamps */
+			if (Log_compareEntries((char*)cur_trace_entry->content, msg_buf) > 0)
+				cur_trace_entry = NULL;
+		}
+
+		if (cur_trace_entry)
+		{
+			fprintf(file, "%s\n", &((char*)(cur_trace_entry->content))[msgstart]);
+			ListNextElement(trace_buffer, &cur_trace_entry);
+		}
+		else
+		{
+			fprintf(file, "%s\n", &msg_buf[7]);
+			if (trace_queue_index != next_index)
+			{
+				Log_formatTraceEntry(&trace_queue[trace_queue_index++]);
+				if (trace_queue_index == trace_settings.max_trace_entries)
+					trace_queue_index = 0;
+			}
+		}
+	}
+	fprintf(file, "========== End of trace dump ==========\n\n");
+	if (file != stdout && file != stderr && file != NULL)
+		fclose(file);
+	rc = 0;
+exit:
+	return rc;
+}
+#endif
+
+

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a8703b5c/thirdparty/paho.mqtt.c/src/Log.h
----------------------------------------------------------------------
diff --git a/thirdparty/paho.mqtt.c/src/Log.h b/thirdparty/paho.mqtt.c/src/Log.h
new file mode 100644
index 0000000..455beb6
--- /dev/null
+++ b/thirdparty/paho.mqtt.c/src/Log.h
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution. 
+ *
+ * The Eclipse Public License is available at 
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at 
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - updates for the async client
+ *******************************************************************************/
+
+#if !defined(LOG_H)
+#define LOG_H
+
+/*BE
+map LOG_LEVELS
+{
+	"TRACE_MAXIMUM" 1
+	"TRACE_MEDIUM" 2
+	"TRACE_MINIMUM" 3
+	"TRACE_PROTOCOL" 4
+
+	"ERROR" 5
+	"SEVERE" 6
+	"FATAL" 7
+}
+BE*/
+
+enum LOG_LEVELS {
+	INVALID_LEVEL = -1,
+	TRACE_MAXIMUM = 1,
+	TRACE_MEDIUM,
+	TRACE_MINIMUM,
+	TRACE_PROTOCOL,
+	LOG_ERROR,
+	LOG_SEVERE,
+	LOG_FATAL,
+};
+
+
+/*BE
+def trace_settings_type
+{
+   n32 map LOG_LEVELS "trace_level"
+   n32 dec "max_trace_entries"
+   n32 dec "trace_output_level"
+}
+BE*/
+typedef struct
+{
+	enum LOG_LEVELS trace_level;	/**< trace level */
+	int max_trace_entries;		/**< max no of entries in the trace buffer */
+	enum LOG_LEVELS trace_output_level;		/**< trace level to output to destination */
+} trace_settings_type;
+
+extern trace_settings_type trace_settings;
+
+#define LOG_PROTOCOL TRACE_PROTOCOL
+#define TRACE_MAX TRACE_MAXIMUM
+#define TRACE_MIN TRACE_MINIMUM
+#define TRACE_MED TRACE_MEDIUM
+
+typedef struct
+{
+	const char* name;
+	const char* value;
+} Log_nameValue;
+
+int Log_initialize(Log_nameValue*);
+void Log_terminate(void);
+
+void Log(enum LOG_LEVELS, int, const char *, ...);
+void Log_stackTrace(enum LOG_LEVELS, int, int, int, const char*, int, int*);
+
+typedef void Log_traceCallback(enum LOG_LEVELS level, const char *message);
+void Log_setTraceCallback(Log_traceCallback* callback);
+void Log_setTraceLevel(enum LOG_LEVELS level);
+
+#endif