Browse Source

Premier commit

Jean-Michel Caricand 2 years ago
parent
commit
9fd66261ee
100 changed files with 25735 additions and 0 deletions
  1. 543 0
      BuildProcessTemplates/DefaultTemplate.11.1.xaml
  2. 0 0
      BuildProcessTemplates/LabDefaultTemplate.11.xaml
  3. 76 0
      BuildProcessTemplates/UpgradeTemplate.xaml
  4. 1656 0
      Doxyfile
  5. 12 0
      LICENSE
  6. 84 0
      Makefile.lib.xml
  7. 97 0
      Makefile.platform.xml
  8. 38 0
      Makefile.xml
  9. 32 0
      README
  10. 14 0
      config/libopc.pc
  11. 53 0
      config/mce/config.h
  12. 189 0
      config/opc/config.h
  13. 1 0
      config/win32-msvc/libxml2-2.7.7/..svnbridge/config.h
  14. 124 0
      config/win32-msvc/libxml2-2.7.7/config.h
  15. 1 0
      config/win32-msvc/libxml2-2.7.7/libxml/..svnbridge/xmlversion.h
  16. 458 0
      config/win32-msvc/libxml2-2.7.7/libxml/xmlversion.h
  17. 1 0
      config/win32-msvc/zlib-1.2.5/..svnbridge/zconf.h
  18. 428 0
      config/win32-msvc/zlib-1.2.5/zconf.h
  19. 174 0
      configure
  20. 1 0
      debian/..svnbridge/rules
  21. 6 0
      debian/README
  22. 5 0
      debian/changelog
  23. 1 0
      debian/compat
  24. 31 0
      debian/control
  25. 33 0
      debian/copyright
  26. 2 0
      debian/libopc-dev.dirs
  27. 6 0
      debian/libopc-dev.install
  28. 2 0
      debian/libopc.install
  29. 15 0
      debian/rules
  30. 1 0
      debian/source/format
  31. 9 0
      debian/source/options
  32. 1124 0
      generate.py
  33. 1124 0
      generate.py.bak
  34. 154 0
      mce/helper.c
  35. 189 0
      mce/helper.h
  36. 422 0
      mce/textreader.c
  37. 464 0
      mce/textreader.h
  38. 297 0
      mce/textwriter.c
  39. 176 0
      mce/textwriter.h
  40. 1 0
      opc/..svnbridge/properties.c
  41. 1 0
      opc/..svnbridge/properties.h
  42. 1496 0
      opc/container.c
  43. 300 0
      opc/container.h
  44. 239 0
      opc/file.c
  45. 200 0
      opc/file.h
  46. 205 0
      opc/helper.c
  47. 60 0
      opc/helper.h
  48. 34 0
      opc/inputstream.c
  49. 74 0
      opc/inputstream.h
  50. 237 0
      opc/internal.h
  51. 132 0
      opc/main.c
  52. 43 0
      opc/opc.c
  53. 73 0
      opc/opc.h
  54. 33 0
      opc/outputstream.c
  55. 71 0
      opc/outputstream.h
  56. 117 0
      opc/part.c
  57. 118 0
      opc/part.h
  58. 292 0
      opc/properties.c
  59. 121 0
      opc/properties.h
  60. 153 0
      opc/relation.c
  61. 140 0
      opc/relation.h
  62. 65 0
      opc/xmlreader.c
  63. 69 0
      opc/xmlreader.h
  64. 53 0
      opc/xmlwriter.c
  65. 57 0
      opc/xmlwriter.h
  66. 1498 0
      opc/zip.c
  67. 255 0
      opc/zip.h
  68. 1 0
      plib/..svnbridge/Makefile.xml
  69. 1 0
      plib/..svnbridge/configure
  70. 44 0
      plib/Makefile.xml
  71. 167 0
      plib/config/msvc/plib/include/plib/plib.h
  72. 4253 0
      plib/configure
  73. 45 0
      plib/configure.ac
  74. 34 0
      plib/source/plib.c
  75. 202 0
      regression.py
  76. 5 0
      sample/..svnbridge/Makefile.xml
  77. 1 0
      sample/..svnbridge/opc_changes.c
  78. 1 0
      sample/..svnbridge/opc_proc.c
  79. 1 0
      sample/..svnbridge/opc_properties.c
  80. 127 0
      sample/Makefile.xml
  81. 165 0
      sample/mce_extract.c
  82. 73 0
      sample/mce_read.c
  83. 550 0
      sample/mce_schema.c
  84. 122 0
      sample/mce_write.c
  85. 103 0
      sample/mcepp.c
  86. 3859 0
      sample/opc_album.c
  87. 283 0
      sample/opc_changes.c
  88. 82 0
      sample/opc_dump.c
  89. 96 0
      sample/opc_extract.c
  90. 370 0
      sample/opc_generate.c
  91. 65 0
      sample/opc_helloworld.c
  92. 100 0
      sample/opc_image.c
  93. 89 0
      sample/opc_mem.c
  94. 94 0
      sample/opc_part.c
  95. 110 0
      sample/opc_proc.c
  96. 122 0
      sample/opc_properties.c
  97. 110 0
      sample/opc_relation.c
  98. 120 0
      sample/opc_text.c
  99. 81 0
      sample/opc_trim.c
  100. 79 0
      sample/opc_type.c

+ 543 - 0
BuildProcessTemplates/DefaultTemplate.11.1.xaml

@@ -0,0 +1,543 @@
+<Activity mc:Ignorable="sad" x:Class="TfsBuild.Process" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mt="clr-namespace:Microsoft.TeamFoundation;assembly=Microsoft.TeamFoundation.Common" xmlns:mtbc="clr-namespace:Microsoft.TeamFoundation.Build.Client;assembly=Microsoft.TeamFoundation.Build.Client" xmlns:mtbw="clr-namespace:Microsoft.TeamFoundation.Build.Workflow;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwt="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Tracking;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mttbb="clr-namespace:Microsoft.TeamFoundation.TestImpact.BuildIntegration.BuildActivities;assembly=Microsoft.TeamFoundation.TestImpact.BuildIntegration" xmlns:mtvc="clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client" xmlns:mtvco="clr-namespace:Microsoft.TeamFoundation.VersionControl.Common;assembly=Microsoft.TeamFoundation.VersionControl.Common" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:sad="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:sad1="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:this="clr-namespace:TfsBuild;" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+  <x:Members>
+    <x:Property Name="BuildSettings" Type="InArgument(mtbwa:BuildSettings)" />
+    <x:Property Name="TestSpecs" Type="InArgument(mtbwa:TestSpecList)" />
+    <x:Property Name="BuildNumberFormat" Type="InArgument(x:String)" />
+    <x:Property Name="SolutionSpecificBuildOutputs" Type="InArgument(x:Boolean)" />
+    <x:Property Name="CleanWorkspace" Type="InArgument(mtbwa:CleanWorkspaceOption)" />
+    <x:Property Name="RunCodeAnalysis" Type="InArgument(mtbwa:CodeAnalysisOption)" />
+    <x:Property Name="SourceAndSymbolServerSettings" Type="InArgument(mtbwa:SourceAndSymbolServerSettings)" />
+    <x:Property Name="AgentSettings" Type="InArgument(mtbwa:AgentSettings)" />
+    <x:Property Name="AssociateChangesetsAndWorkItems" Type="InArgument(x:Boolean)" />
+    <x:Property Name="CreateWorkItem" Type="InArgument(x:Boolean)" />
+    <x:Property Name="MSBuildArguments" Type="InArgument(x:String)" />
+    <x:Property Name="MSBuildPlatform" Type="InArgument(mtbwa:ToolPlatform)" />
+    <x:Property Name="MSBuildMultiProc" Type="InArgument(x:Boolean)" />
+    <x:Property Name="PerformTestImpactAnalysis" Type="InArgument(x:Boolean)" />
+    <x:Property Name="CreateLabel" Type="InArgument(x:Boolean)" />
+    <x:Property Name="DisableTests" Type="InArgument(x:Boolean)" />
+    <x:Property Name="GetVersion" Type="InArgument(x:String)" />
+    <x:Property Name="PrivateDropLocation" Type="InArgument(x:String)" />
+    <x:Property Name="Verbosity" Type="InArgument(mtbw:BuildVerbosity)" />
+    <x:Property Name="Metadata" Type="mtbw:ProcessParameterMetadataCollection" />
+    <x:Property Name="SupportedReasons" Type="mtbc:BuildReason" />
+    <x:Property Name="BuildProcessVersion" Type="x:String" />
+  </x:Members>
+  <this:Process.BuildSettings>[New Microsoft.TeamFoundation.Build.Workflow.Activities.BuildSettings()]</this:Process.BuildSettings>
+  <this:Process.DisableTests>[False]</this:Process.DisableTests>
+  <this:Process.TestSpecs>[New Microsoft.TeamFoundation.Build.Workflow.Activities.TestSpecList(New Microsoft.TeamFoundation.Build.Workflow.Activities.AgileTestPlatformSpec("**\*test*.dll"))]</this:Process.TestSpecs>
+  <this:Process.BuildNumberFormat>["$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r)"]</this:Process.BuildNumberFormat>
+  <this:Process.SolutionSpecificBuildOutputs>[False]</this:Process.SolutionSpecificBuildOutputs>
+  <this:Process.AssociateChangesetsAndWorkItems>[True]</this:Process.AssociateChangesetsAndWorkItems>
+  <this:Process.CreateWorkItem>[True]</this:Process.CreateWorkItem>
+  <this:Process.CleanWorkspace>[Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.All]</this:Process.CleanWorkspace>
+  <this:Process.MSBuildArguments>
+    <InArgument x:TypeArguments="x:String" />
+  </this:Process.MSBuildArguments>
+  <this:Process.RunCodeAnalysis>[Microsoft.TeamFoundation.Build.Workflow.Activities.CodeAnalysisOption.AsConfigured]</this:Process.RunCodeAnalysis>
+  <this:Process.MSBuildMultiProc>[True]</this:Process.MSBuildMultiProc>
+  <this:Process.MSBuildPlatform>[Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto]</this:Process.MSBuildPlatform>
+  <this:Process.PerformTestImpactAnalysis>[True]</this:Process.PerformTestImpactAnalysis>
+  <this:Process.SourceAndSymbolServerSettings>[New Microsoft.TeamFoundation.Build.Workflow.Activities.SourceAndSymbolServerSettings(True, Nothing)]</this:Process.SourceAndSymbolServerSettings>
+  <this:Process.CreateLabel>[True]</this:Process.CreateLabel>
+  <this:Process.GetVersion>
+    <InArgument x:TypeArguments="x:String" />
+  </this:Process.GetVersion>
+  <this:Process.AgentSettings>[New Microsoft.TeamFoundation.Build.Workflow.Activities.AgentSettings() With {.MaxWaitTime = New System.TimeSpan(4, 0, 0), .MaxExecutionTime = New System.TimeSpan(0, 0, 0), .TagComparison = Microsoft.TeamFoundation.Build.Workflow.Activities.TagComparison.MatchExactly }]</this:Process.AgentSettings>
+  <this:Process.Verbosity>[Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal]</this:Process.Verbosity>
+  <this:Process.Metadata>
+    <mtbw:ProcessParameterMetadataCollection>
+      <mtbw:ProcessParameterMetadata BrowsableWhen="EditingDefinition" Category="#300 Advanced" DisplayName="MSBuild Multi-Proc" Description="Enable MSBuid Multi-proc to build your solutions' projects in parallel, when possible, using all available processors on the build server." ParameterName="MSBuildMultiProc" />
+      <mtbw:ProcessParameterMetadata BrowsableWhen="EditingDefinition" Category="#300 Advanced" DisplayName="Solution Specific Build Outputs" Description="True will put build outputs into folders based on the solution name. False will put all build outputs into the same folder." ParameterName="SolutionSpecificBuildOutputs" />
+    </mtbw:ProcessParameterMetadataCollection>
+  </this:Process.Metadata>
+  <this:Process.SupportedReasons>All</this:Process.SupportedReasons>
+  <this:Process.BuildProcessVersion>11.0</this:Process.BuildProcessVersion>  
+  <mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
+  <Sequence mtbwt:BuildTrackingParticipant.Importance="None">
+    <Sequence.Variables>
+      <Variable x:TypeArguments="mtbc:IBuildDetail" Name="BuildDetail" />
+      <Variable x:TypeArguments="x:String"  Name="DropLocation" />
+    </Sequence.Variables>
+    <mtbwa:GetBuildDetail DisplayName="Get the Build" Result="[BuildDetail]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+    <Sequence DisplayName="Update Drop Location" mtbwt:BuildTrackingParticipant.Importance="Low">
+      <mtbwa:InvokeForReason DisplayName="Update Build Number for Triggered Builds" Reason="Triggered">
+        <mtbwa:UpdateBuildNumber BuildNumberFormat="[BuildNumberFormat]" DisplayName="Update Build Number" />
+      </mtbwa:InvokeForReason>
+      <If Condition="[(Not String.IsNullOrEmpty(BuildDetail.DropLocationRoot)) AndAlso (BuildDetail.Reason And Microsoft.TeamFoundation.Build.Client.BuildReason.Triggered) = BuildDetail.Reason]" DisplayName="If Build Reason is Triggered" mtbwt:BuildTrackingParticipant.Importance="Low">
+        <If.Then>
+          <Sequence mtbwt:BuildTrackingParticipant.Importance="None">
+            <Assign x:TypeArguments="x:String" mtbwt:BuildTrackingParticipant.Importance="None" Value="[BuildDropProvider.CombinePaths(BuildDetail.DropLocationRoot, BuildDetail.BuildDefinition.Name, BuildDetail.BuildNumber)]" To="[DropLocation]" />
+            <mtbwa:SetBuildProperties DisplayName="Set Drop Location" DropLocation="[DropLocation]" PropertiesToSet="DropLocation" mtbwt:BuildTrackingParticipant.Importance="Low" />
+          </Sequence>
+        </If.Then>
+      </If>
+      <If Condition="[(Not String.IsNullOrEmpty(PrivateDropLocation)) AndAlso BuildDetail.Reason = Microsoft.TeamFoundation.Build.Client.BuildReason.ValidateShelveset]" DisplayName="If Build Reason is ValidateShelveset" mtbwt:BuildTrackingParticipant.Importance="Low">
+        <If.Then>
+          <Sequence mtbwt:BuildTrackingParticipant.Importance="None">
+            <Assign x:TypeArguments="x:String" Value="[BuildDropProvider.CombinePaths(PrivateDropLocation, BuildDetail.BuildDefinition.Name, BuildDetail.BuildNumber)]" To="[DropLocation]" mtbwt:BuildTrackingParticipant.Importance="None" />
+            <mtbwa:SetBuildProperties DisplayName="Set Drop Location for Private Build" DropLocation="[DropLocation]" PropertiesToSet="DropLocation" mtbwt:BuildTrackingParticipant.Importance="Low" />
+          </Sequence>
+        </If.Then>
+      </If>
+    </Sequence>
+    <mtbwa:AgentScope DisplayName="Run On Agent" MaxExecutionTime="[AgentSettings.MaxExecutionTime]" MaxWaitTime="[AgentSettings.MaxWaitTime]" ReservationSpec="[AgentSettings.GetAgentReservationSpec()]">
+      <mtbwa:AgentScope.Variables>
+        <Variable x:TypeArguments="mtbc:IBuildAgent" Name="BuildAgent" />
+        <Variable x:TypeArguments="mtvc:Workspace" Name="Workspace" />
+        <Variable x:TypeArguments="x:String" Name="BuildDirectory" />
+        <Variable x:TypeArguments="x:String" Default="[BuildDetail.BuildNumber]" Name="LabelName" />
+        <Variable x:TypeArguments="x:String" Name="WorkspaceName" />
+        <Variable x:TypeArguments="x:String" Name="SourcesDirectory" />
+        <Variable x:TypeArguments="x:String" Name="BinariesDirectory" />
+        <Variable x:TypeArguments="x:String" Name="TestResultsDirectory" />
+      </mtbwa:AgentScope.Variables>
+      <Sequence DisplayName="Initialize Variables" mtbwt:BuildTrackingParticipant.Importance="Low">
+        <mtbwa:GetBuildAgent DisplayName="Get the Agent" Result="[BuildAgent]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+        <mtbwa:GetBuildDirectory DisplayName="Get the Build Directory" Result="[BuildDirectory]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+        <Assign x:TypeArguments="x:String" DisplayName="Initialize Workspace Name" To="[WorkspaceName]" Value="[String.Format(&quot;{0}_{1}_{2}&quot;, BuildDetail.BuildDefinition.Id, Microsoft.TeamFoundation.LinkingUtilities.DecodeUri(BuildAgent.Uri.AbsoluteUri).ToolSpecificId, BuildAgent.ServiceHost.Name)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+        <Assign x:TypeArguments="x:String" DisplayName="Initialize Sources Directory" To="[SourcesDirectory]" Value="[String.Format(&quot;{0}\Sources&quot;, BuildDirectory)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+        <Assign x:TypeArguments="x:String" DisplayName="Initialize Binaries Directory" To="[BinariesDirectory]" Value="[String.Format(&quot;{0}\Binaries&quot;, BuildDirectory)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+        <Assign x:TypeArguments="x:String" DisplayName="Initialize TestResults Directory" To="[TestResultsDirectory]" Value="[String.Format(&quot;{0}\TestResults&quot;, BuildDirectory)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+        <If Condition="[Not BuildSettings.HasPlatformConfigurations]" DisplayName="If Not BuildSettings.HasPlatformConfigurations" mtbwt:BuildTrackingParticipant.Importance="Low">
+          <If.Then>
+            <AddToCollection x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="Use Default Platform Configuration" Collection="[BuildSettings.PlatformConfigurations]" Item="[Microsoft.TeamFoundation.Build.Workflow.Activities.PlatformConfiguration.Default]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+          </If.Then>
+        </If>
+        <If Condition="[WorkspaceName.Length &gt; Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize]" DisplayName="If WorkspaceName &gt; MaxSize" mtbwt:BuildTrackingParticipant.Importance="Low">
+          <If.Then>
+            <Sequence mtbwt:BuildTrackingParticipant.Importance="None">
+              <mtbwa:WriteBuildWarning DisplayName="Write Workspace Size Warning" Message="[String.Format(&quot;The workspace name '{0}' exceeds the maximum allowed limit of '{1}' characters. Truncating it to match the maximum limit.&quot;, WorkspaceName, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize)]" />
+              <Assign x:TypeArguments="x:String" DisplayName="Truncate WorkspaceName to MaxSize" To="[WorkspaceName]" Value="[WorkspaceName.Substring(0, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize).TrimEnd()]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+            </Sequence>
+          </If.Then>
+        </If>
+      </Sequence>
+      <Sequence DisplayName="Initialize Workspace" mtbwt:BuildTrackingParticipant.Importance="Low">
+        <mtbwa:DeleteDirectory Directory="[TestResultsDirectory]" DisplayName="Delete Test Results Directory" Recursive="[True]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+        <If Condition="[Not CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.None]" DisplayName="If Not CleanWorkspace = CleanWorkspaceOption.None" mtbwt:BuildTrackingParticipant.Importance="Low">
+          <If.Then>
+            <mtbwa:DeleteDirectory Directory="[BinariesDirectory]" DisplayName="Delete Binaries Directory" mtbwt:BuildTrackingParticipant.Importance="Low" />
+          </If.Then>
+        </If>
+        <If Condition="[CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.All]" DisplayName="If CleanWorkspace = CleanWorkspaceOption.All" mtbwt:BuildTrackingParticipant.Importance="Low">
+          <If.Then>
+            <Sequence DisplayName="Delete Workspace and Sources Directory" mtbwt:BuildTrackingParticipant.Importance="Low">
+              <mtbwa:DeleteWorkspace DeleteLocalItems="[True]" DisplayName="Delete Workspace" Name="[WorkspaceName]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+              <mtbwa:DeleteDirectory Directory="[SourcesDirectory]" DisplayName="Delete Sources Directory" mtbwt:BuildTrackingParticipant.Importance="Low" />
+            </Sequence>
+          </If.Then>
+        </If>
+        <mtbwa:CreateWorkspace BuildDirectory="[BuildDirectory]" Comment="[&quot;Workspace Created by Team Build&quot;]" DisplayName="Create Workspace" Name="[WorkspaceName]" Result="[Workspace]" SourcesDirectory="[SourcesDirectory]" />
+        <If Condition="[CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.Outputs]" DisplayName="If CleanWorkspace = CleanWorkspaceOption.Outputs" mtbwt:BuildTrackingParticipant.Importance="Low">
+          <If.Then>
+            <ForEach x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="For Each Configuration in BuildSettings.PlatformConfigurations" Values="[BuildSettings.PlatformConfigurations]" mtbwt:BuildTrackingParticipant.Importance="Low">
+              <ActivityAction x:TypeArguments="mtbwa:PlatformConfiguration">
+                <ActivityAction.Argument>
+                  <DelegateInArgument x:TypeArguments="mtbwa:PlatformConfiguration" Name="platformConfiguration" />
+                </ActivityAction.Argument>
+                <Sequence DisplayName="Clean Configuration">
+                  <If Condition="[BuildSettings.HasProjectsToBuild]" DisplayName="If BuildSettings.HasProjectsToBuild" mtbwt:BuildTrackingParticipant.Importance="Low">
+                    <If.Then>
+                      <ForEach x:TypeArguments="x:String" DisplayName="For Each Project in BuildSettings.ProjectsToBuild" Values="[BuildSettings.ProjectsToBuild]" mtbwt:BuildTrackingParticipant.Importance="Low">
+                        <ActivityAction x:TypeArguments="x:String">
+                          <ActivityAction.Argument>
+                            <DelegateInArgument x:TypeArguments="x:String" Name="serverBuildProjectItem" />
+                          </ActivityAction.Argument>
+                          <Sequence DisplayName="Clean Project" mtbwt:BuildTrackingParticipant.Importance="Low">
+                            <Sequence.Variables>
+                              <Variable x:TypeArguments="x:String" Name="localBuildProjectItem" />
+                            </Sequence.Variables>
+                            <mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Paths to Local Paths" Input="[serverBuildProjectItem]" Result="[localBuildProjectItem]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                            <If Condition="[System.IO.File.Exists(localBuildProjectItem)]" DisplayName="If File.Exists(Project)" mtbwt:BuildTrackingParticipant.Importance="Low">
+                              <If.Then>
+                                <mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, MSBuildArguments)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" MaxProcesses="[If (MSBuildMultiProc, 0, 1)]" OutDir="[BinariesDirectory]" Platform="[platformConfiguration.Platform]" Project="[localBuildProjectItem]" Targets="[New String() { &quot;Clean&quot; }]" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
+                              </If.Then>
+                            </If>
+                          </Sequence>
+                        </ActivityAction>
+                      </ForEach>
+                    </If.Then>
+                  </If>
+                </Sequence>
+              </ActivityAction>
+            </ForEach>
+          </If.Then>
+        </If>
+        <mtbwa:SyncWorkspace DisplayName="Get Workspace" VersionOverride="[GetVersion]" Workspace="[Workspace]">
+          <mtbwa:SyncWorkspace.RequestsFailed>
+            <ActivityAction x:TypeArguments="scg:ICollection(mtbc:IQueuedBuild)">
+              <ActivityAction.Argument>
+                <DelegateInArgument x:TypeArguments="scg:ICollection(mtbc:IQueuedBuild)" Name="failedRequests" />
+              </ActivityAction.Argument>
+              <mtbwa:RetryRequests Behavior="[Microsoft.TeamFoundation.Build.Workflow.Activities.RetryBehavior.DoNotBatch]" DisplayName="Mark Requests for Retry" Requests="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+            </ActivityAction>
+          </mtbwa:SyncWorkspace.RequestsFailed>
+        </mtbwa:SyncWorkspace>
+      </Sequence>
+      <If Condition="[CreateLabel]" DisplayName="If CreateLabel" mtbwt:BuildTrackingParticipant.Importance="Low">
+        <If.Then>
+          <mtbwa:InvokeForReason DisplayName="Create and Set Label for non-Shelveset Builds" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
+            <mtbwa:LabelWorkspace Comment="[&quot;Label Created by Team Build&quot;]" DisplayName="Create Label" Name="[LabelName]" Scope="[String.Format(&quot;$/{0}&quot;, BuildDetail.BuildDefinition.TeamProject)]" Workspace="[Workspace]" />
+            <mtbwa:SetBuildProperties DisplayName="Set Label on BuildDetail" LabelName="[String.Format(&quot;{0}@$/{1}&quot;, LabelName, BuildDetail.BuildDefinition.TeamProject)]" PropertiesToSet="LabelName" mtbwt:BuildTrackingParticipant.Importance="Low" />
+          </mtbwa:InvokeForReason>
+        </If.Then>
+        <If.Else>
+          <mtbwa:WriteBuildMessage DisplayName="Write Message" Message="Not Labeling sources" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" />
+        </If.Else>
+      </If>
+      <TryCatch DisplayName="Try Compile, Test, and Associate Changesets and Work Items" mtbwt:BuildTrackingParticipant.Importance="Low">
+        <TryCatch.Finally>
+          <Sequence DisplayName="Revert Workspace and Copy Files to Drop Location" mtbwt:BuildTrackingParticipant.Importance="Low">
+            <mtbwa:InvokeForReason DisplayName="Revert Workspace for Shelveset Builds" Reason="CheckInShelveset, ValidateShelveset">
+              <mtbwa:RevertWorkspace DisplayName="Revert Workspace" Workspace="[Workspace]" />
+            </mtbwa:InvokeForReason>
+            <If  Condition="[Not String.IsNullOrEmpty(DropLocation)]" DisplayName="If DropLocation is Set" mtbwt:BuildTrackingParticipant.Importance="Low">
+              <If.Then>
+                <mtbwa:CopyDirectory DisplayName="Drop Files to Drop Location" Source="[BinariesDirectory]" Destination="[DropLocation]" />
+              </If.Then>
+            </If>
+          </Sequence>
+        </TryCatch.Finally>
+        <TryCatch.Try>
+          <Sequence mtbwt:BuildTrackingParticipant.Importance="None">
+            <Sequence.Variables>
+              <Variable x:TypeArguments="s:Exception" Name="compilationException" />
+              <Variable x:TypeArguments="scg:IList(mtvc:Changeset)" Name="associatedChangesets" />
+              <Variable x:TypeArguments="s:Boolean" Name="treatTestFailureAsBuildFailure" />
+            </Sequence.Variables>
+            <Parallel DisplayName="Compile, Test, and Associate Changesets and Work Items">
+              <TryCatch DisplayName="Try Compile and Test" mtbwt:BuildTrackingParticipant.Importance="Low">
+                <TryCatch.Try>
+                  <Sequence DisplayName="Compile and Test">
+                    <ForEach x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="For Each Configuration in BuildSettings.PlatformConfigurations" Values="[BuildSettings.PlatformConfigurations]" mtbwt:BuildTrackingParticipant.Importance="Low">
+                      <ActivityAction x:TypeArguments="mtbwa:PlatformConfiguration">
+                        <ActivityAction.Argument>
+                          <DelegateInArgument x:TypeArguments="mtbwa:PlatformConfiguration" Name="platformConfiguration" />
+                        </ActivityAction.Argument>
+                        <Sequence DisplayName="Compile and Test for Configuration" mtbwt:BuildTrackingParticipant.Importance="Low">
+                          <Sequence.Variables>
+                            <Variable x:TypeArguments="x:String" Name="outputDirectory" />
+                            <Variable x:TypeArguments="x:String" Name="logFileDropLocation" />
+                          </Sequence.Variables>
+                          <Sequence DisplayName="Initialize Variables" mtbwt:BuildTrackingParticipant.Importance="Low">
+                            <Assign x:TypeArguments="x:String" DisplayName="Create OutputDirectory Per Platform and Configuration" To="[outputDirectory]" Value="[If (platformConfiguration.IsEmpty Or BuildSettings.PlatformConfigurations.Count = 1, BinariesDirectory, If (platformConfiguration.IsPlatformEmptyOrAnyCpu, BinariesDirectory + &quot;\&quot; + platformConfiguration.Configuration, BinariesDirectory + &quot;\&quot; + platformConfiguration.Platform + &quot;\&quot; + platformConfiguration.Configuration))]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                            <If Condition="[Not String.IsNullOrEmpty(DropLocation)]" DisplayName="If DropLocation is Set" mtbwt:BuildTrackingParticipant.Importance="Low">
+                              <If.Then>
+                                <Assign x:TypeArguments="x:String" DisplayName="Initialize LogFile Drop Location" To="[logFileDropLocation]" Value="[If (platformConfiguration.IsEmpty Or BuildSettings.PlatformConfigurations.Count = 1, BuildDropProvider.CombinePaths(DropLocation, &quot;logs&quot;), If (platformConfiguration.IsPlatformEmptyOrAnyCpu, BuildDropProvider.CombinePaths(DropLocation, &quot;logs&quot;, platformConfiguration.Configuration), BuildDropProvider.CombinePaths(DropLocation, &quot;logs&quot;, platformConfiguration.Platform, platformConfiguration.Configuration)))]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                              </If.Then>
+                            </If>
+                          </Sequence>
+                          <If Condition="[BuildSettings.HasProjectsToBuild]" DisplayName="If BuildSettings.HasProjectsToBuild" mtbwt:BuildTrackingParticipant.Importance="Low">
+                            <If.Then>
+                              <ForEach x:TypeArguments="x:String" DisplayName="For Each Project in BuildSettings.ProjectsToBuild" Values="[BuildSettings.ProjectsToBuild]" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                <ActivityAction x:TypeArguments="x:String">
+                                  <ActivityAction.Argument>
+                                    <DelegateInArgument x:TypeArguments="x:String" Name="serverBuildProjectItem" />
+                                  </ActivityAction.Argument>
+                                  <TryCatch DisplayName="Try to Compile the Project" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                    <TryCatch.Try>
+                                      <Sequence DisplayName="Compile the Project" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                        <Sequence.Variables>
+                                          <Variable x:TypeArguments="x:String" Name="localProject" />
+                                          <Variable x:TypeArguments="x:String" Name="outputDirectoryPerProject" Default="[outputDirectory]" />
+                                        </Sequence.Variables>
+                                        <mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" Input="[serverBuildProjectItem]" Result="[localProject]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                        <If Condition="[SolutionSpecificBuildOutputs]" DisplayName="If Build Outputs are Solution-Specific" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                          <If.Then>
+                                            <Sequence DisplayName="Update Output Directory" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                              <Assign x:TypeArguments="x:String" DisplayName="Set Solution-Specific Output Directory" To="[outputDirectoryPerProject]" Value="[System.IO.Path.Combine(outputDirectory, System.IO.Path.GetFileNameWithoutExtension(localProject))]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                              <If DisplayName="If Output Directory Exists" Condition="[System.IO.Directory.Exists(outputDirectoryPerProject)]" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                <If.Then>
+                                                  <mtbwa:WriteBuildWarning DisplayName="Write Duplicate Project Names Warning" Message="[String.Format(&quot;{0} conflicts with another solution/project. Build outputs for solutions/projects with the same name will be copied to the same directory. To separate the build outputs, change the name of one of the solutions/projects.&quot;, System.IO.Path.GetFileNameWithoutExtension(localProject))]" />
+                                                </If.Then>
+                                              </If>
+                                            </Sequence>
+                                          </If.Then>
+                                        </If>
+                                        <mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, MSBuildArguments)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" LogFileDropLocation="[logFileDropLocation]" MaxProcesses="[If (MSBuildMultiProc, 0, 1)]" OutDir="[outputDirectoryPerProject]" Platform="[platformConfiguration.Platform]" Project="[localProject]" RunCodeAnalysis="[RunCodeAnalysis]" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
+                                      </Sequence>
+                                    </TryCatch.Try>
+                                    <TryCatch.Catches>
+                                      <Catch x:TypeArguments="s:Exception">
+                                        <ActivityAction x:TypeArguments="s:Exception">
+                                          <ActivityAction.Argument>
+                                            <DelegateInArgument x:TypeArguments="s:Exception" Name="ex" />
+                                          </ActivityAction.Argument>
+                                          <Sequence DisplayName="Handle Exception">
+                                            <Sequence.Variables>
+                                              <Variable x:TypeArguments="scg:ICollection(mtbc:IQueuedBuild)" Name="failedRequests" />
+                                            </Sequence.Variables>
+                                            <mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]" DisplayName="Set CompilationStatus to Failed" PropertiesToSet="CompilationStatus" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                            <If Condition="[CreateWorkItem]" DisplayName="If CreateWorkItem" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                              <If.Then>
+                                                <mtbwa:InvokeForReason DisplayName="Create Work Item for non-Shelveset Builds" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
+                                                  <mtbwa:OpenWorkItem AssignedTo="[BuildDetail.RequestedFor]" Comment="[&quot;This work item was created by TFS Build on a build failure.&quot;]" CustomFields="[New Dictionary(Of String, String) From { {&quot;System.Reason&quot;, &quot;Build Failure&quot;}, {&quot;Microsoft.VSTS.TCM.ReproSteps&quot;, &quot;Start the build using TFS Build&quot;}, {&quot;Priority&quot;, &quot;1&quot;}, {&quot;Severity&quot;, &quot;1 - Critical&quot;} }]" DisplayName="Create Work Item" Title="[String.Format(&quot;Build Failure in Build: {0}&quot;, BuildDetail.BuildNumber)]" Type="[&quot;Bug&quot;]" />
+                                                </mtbwa:InvokeForReason>
+                                              </If.Then>
+                                            </If>
+                                            <mtbwa:GetApprovedRequests DisplayName="Get Requests Approved for Check In" Result="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="None" />
+                                            <mtbwa:RetryRequests Behavior="[Microsoft.TeamFoundation.Build.Workflow.Activities.RetryBehavior.DoNotBatch]" DisplayName="Mark Requests for Retry" Requests="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                            <Rethrow DisplayName="Rethrow the exception so the build will stop" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                          </Sequence>
+                                        </ActivityAction>
+                                      </Catch>
+                                    </TryCatch.Catches>
+                                  </TryCatch>
+                                </ActivityAction>
+                              </ForEach>
+                            </If.Then>
+                          </If>
+                          <If Condition="[Not DisableTests]" DisplayName="If Not DisableTests" mtbwt:BuildTrackingParticipant.Importance="Low">
+                            <If.Then>
+                              <Sequence DisplayName="Run Tests" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                <If Condition="[Not TestSpecs Is Nothing]" DisplayName="If Not TestSpecs Is Nothing" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                  <If.Then>
+                                    <ForEach x:TypeArguments="mtbwa:TestSpec" DisplayName="For Each TestSpec in TestSpecs" Values="[TestSpecs]" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                      <ActivityAction x:TypeArguments="mtbwa:TestSpec">
+                                        <ActivityAction.Argument>
+                                          <DelegateInArgument x:TypeArguments="mtbwa:TestSpec" Name="spec" />
+                                        </ActivityAction.Argument>
+                                        <TryCatch DisplayName="Try Run Tests" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                          <TryCatch.Try>
+                                            <If Condition="[TypeOf spec Is Microsoft.TeamFoundation.Build.Workflow.Activities.AgileTestPlatformSpec]" DisplayName="If spec Is AgileTestPlatformSpec" mtbwt:BuildTrackingParticipant.Importance="None">
+                                              <If.Then>
+                                                <Sequence DisplayName="Run Visual Studio Test Runner for Test Sources" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                  <Sequence.Variables>
+                                                    <Variable x:TypeArguments="mtbwa:AgileTestPlatformSpec" Name="agileTestPlatformAssembly" />
+                                                    <Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="agileTestPlatformAssemblies" />
+                                                  </Sequence.Variables>
+                                                  <Assign x:TypeArguments="mtbwa:AgileTestPlatformSpec" DisplayName="Assign spec to agileTestPlatformAssembly" To="[agileTestPlatformAssembly]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.AgileTestPlatformSpec)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                  <mtbwa:FindMatchingFiles DisplayName="Find Visual Studio Test Platform Test Assemblies" MatchPattern="[String.Format(&quot;{0}\{1}&quot;, outputDirectory, agileTestPlatformAssembly.AssemblyFileSpec)]" Result="[agileTestPlatformAssemblies]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                  <If Condition="[agileTestPlatformAssemblies.Count() &gt; 0]" DisplayName="If Visual Studio Test Platform Test Assemblies Found" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                    <If.Then>
+                                                      <If Condition="[agileTestPlatformAssembly.HasRunSettingsFile]" DisplayName="If agileTestPlatformAssembly.HasRunSettingsFile" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                        <If.Then>
+                                                          <Sequence DisplayName="Find Run Settings File And Run Visual Studio Test Runner" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                            <Sequence.Variables>
+                                                              <Variable x:TypeArguments="x:String" Name="localRunSettings" />
+                                                            </Sequence.Variables>
+                                                            <mtbwa:GenerateRunSettings DisplayName="Generate Run Settings File" RunSettingsForTestRun="[agileTestPlatformAssembly.RunSettingsForTestRun]" Result="[localRunSettings]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                            <mtbwa:RunTests DisplayName="Run Visual Studio Test Runner for Test Sources" RunName="[agileTestPlatformAssembly.RunName]" Flavor="[platformConfiguration.Configuration]" Platform="[platformConfiguration.Platform]" TestSources="[agileTestPlatformAssemblies]" RunSettings="[localRunSettings]" TestCaseFilter="[agileTestPlatformAssembly.TestCaseFilter]" ExecutionPlatform="[agileTestPlatformAssembly.ExecutionPlatform]" />
+                                                          </Sequence>
+                                                        </If.Then>
+                                                        <If.Else>
+                                                          <mtbwa:RunTests DisplayName="Run Visual Studio Test Runner for Test Sources" RunName="[agileTestPlatformAssembly.RunName]" Flavor="[platformConfiguration.Configuration]" Platform="[platformConfiguration.Platform]" TestSources="[agileTestPlatformAssemblies]" TestCaseFilter="[agileTestPlatformAssembly.TestCaseFilter]" ExecutionPlatform="[agileTestPlatformAssembly.ExecutionPlatform]" />
+                                                        </If.Else>
+                                                      </If>
+                                                    </If.Then>
+                                                  </If>
+                                                </Sequence>
+                                              </If.Then>
+                                              <If.Else>
+                                                <If Condition="[TypeOf spec Is Microsoft.TeamFoundation.Build.Workflow.Activities.TestMetadataFileSpec]" DisplayName="If spec Is TestMetadataFileSpec" mtbwt:BuildTrackingParticipant.Importance="None">
+                                                  <If.Then>
+                                                    <Sequence DisplayName="Run MSTest for Metadata File">
+                                                      <Sequence.Variables>
+                                                        <Variable x:TypeArguments="mtbwa:TestMetadataFileSpec" Name="testMetadataFile" />
+                                                        <Variable x:TypeArguments="x:String" Name="localTestMetadata" />
+                                                      </Sequence.Variables>
+                                                      <Assign x:TypeArguments="mtbwa:TestMetadataFileSpec" DisplayName="Assign spec to testMetadataFile" To="[testMetadataFile]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.TestMetadataFileSpec)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                      <mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" Input="[testMetadataFile.MetadataFileName]" Result="[localTestMetadata]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                      <mtbwa:MSTest RunTitle="[testMetadataFile.RunName]" Category="[testMetadataFile.CategoryFilter]" DisplayName="Run MSTest for Metadata File" Flavor="[platformConfiguration.Configuration]" MaxPriority="[testMetadataFile.MaximumPriority]" MinPriority="[testMetadataFile.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestLists="[testMetadataFile.TestLists]" TestMetadata="[localTestMetadata]" TestSettings="[String.Empty]" CommandLineArguments="[testMetadataFile.MSTestCommandLineArgs]" />
+                                                    </Sequence>
+                                                  </If.Then>
+                                                  <If.Else>
+                                                    <Sequence DisplayName="Run MSTest for Test Assemblies" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                      <Sequence.Variables>
+                                                        <Variable x:TypeArguments="mtbwa:TestAssemblySpec" Name="testAssembly" />
+                                                        <Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="testAssemblies" />
+                                                        <Variable x:TypeArguments="x:String" Default="[String.Empty]" Name="testFlavor" />
+                                                        <Variable x:TypeArguments="x:String" Default="[String.Empty]" Name="testPlatform" />
+                                                      </Sequence.Variables>
+                                                      <Assign x:TypeArguments="mtbwa:TestAssemblySpec" DisplayName="Assign spec to testAssembly" To="[testAssembly]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.TestAssemblySpec)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                      <mtbwa:FindMatchingFiles DisplayName="Find Test Assemblies" MatchPattern="[String.Format(&quot;{0}\{1}&quot;, outputDirectory, testAssembly.AssemblyFileSpec)]" Result="[testAssemblies]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                      <If Condition="[testAssemblies.Count() &gt; 0]" DisplayName="If Test Assemblies Found" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                        <If.Then>
+                                                          <If Condition="[testAssembly.HasTestSettingsFile]" DisplayName="If testAssembly.HasTestSettingsFile" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                            <If.Then>
+                                                              <Sequence DisplayName="Find Test Settings File And Run MSTest" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                                <Sequence.Variables>
+                                                                  <Variable x:TypeArguments="x:String" Name="localTestSettings" />
+                                                                </Sequence.Variables>
+                                                                <mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" Input="[testAssembly.TestSettingsFileName]" Result="[localTestSettings]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                                <mtbwa:MSTest RunTitle="[testAssembly.RunName]" Category="[testAssembly.CategoryFilter]" DisplayName="Run MSTest for Test Assemblies" Flavor="[platformConfiguration.Configuration]" MaxPriority="[testAssembly.MaximumPriority]" MinPriority="[testAssembly.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestContainers="[testAssemblies]" TestSettings="[localTestSettings]" CommandLineArguments="[testAssembly.MSTestCommandLineArgs]" />
+                                                              </Sequence>
+                                                            </If.Then>
+                                                            <If.Else>
+                                                              <mtbwa:MSTest RunTitle="[testAssembly.RunName]" Category="[testAssembly.CategoryFilter]" DisplayName="Run MSTest for Test Assemblies" Flavor="[platformConfiguration.Configuration]" MaxPriority="[testAssembly.MaximumPriority]" MinPriority="[testAssembly.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestContainers="[testAssemblies]" CommandLineArguments="[testAssembly.MSTestCommandLineArgs]" />
+                                                            </If.Else>
+                                                          </If>
+                                                        </If.Then>
+                                                      </If>
+                                                    </Sequence>
+                                                  </If.Else>
+                                                </If>
+                                              </If.Else>
+                                            </If>
+                                          </TryCatch.Try>
+                                          <TryCatch.Catches>
+                                            <Catch x:TypeArguments="s:Exception">
+                                              <ActivityAction x:TypeArguments="s:Exception">
+                                                <ActivityAction.Argument>
+                                                  <DelegateInArgument x:TypeArguments="s:Exception" Name="testException" />
+                                                </ActivityAction.Argument>
+                                                <Sequence DisplayName="Handle Test Run Exception">
+                                                  <Sequence.Variables>
+                                                    <Variable x:TypeArguments="scg:ICollection(mtbc:IQueuedBuild)" Name="failedRequests" />
+                                                  </Sequence.Variables>
+                                                  <If Condition="[Not (TypeOf testException Is Microsoft.TeamFoundation.Build.Workflow.Activities.TestFailureException)]" DisplayName="If testException is NOT TestFailureException" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                    <If.Then>
+                                                      <mtbwa:WriteBuildError DisplayName="Write Test Failure Message" Message="[testException.Message]" />
+                                                    </If.Then>
+                                                  </If>
+                                                  <mtbwa:SetBuildProperties DisplayName="Set TestStatus to Failed" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                  <If Condition="[spec.FailBuildOnFailure]" DisplayName="If spec.FailBuildOnFailure" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                                    <If.Then>
+                                                      <Assign x:TypeArguments="s:Boolean" DisplayName="Set treatTestFailureAsBuildFailure to True" To="[treatTestFailureAsBuildFailure]" Value="[True]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                    </If.Then>
+                                                  </If>
+                                                  <mtbwa:GetApprovedRequests DisplayName="Get Requests Approved for Check In" Result="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="None" />
+                                                  <mtbwa:RetryRequests Behavior="[Microsoft.TeamFoundation.Build.Workflow.Activities.RetryBehavior.DoNotBatch]" DisplayName="Mark Requests for Retry" Requests="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                                                </Sequence>
+                                              </ActivityAction>
+                                            </Catch>
+                                          </TryCatch.Catches>
+                                        </TryCatch>
+                                      </ActivityAction>
+                                    </ForEach>
+                                  </If.Then>
+                                </If>
+                              </Sequence>
+                            </If.Then>
+                            <If.Else>
+                              <If Condition="[(Not TestSpecs Is Nothing) And (TestSpecs.Count > 0)]" DisplayName="If TestSpecs Is Not Nothing or Empty" mtbwt:BuildTrackingParticipant.Importance="Low">
+                                <If.Then>
+                                  <mtbwa:WriteBuildWarning DisplayName="Write Warning" Message="No automated tests will be run for this build because tests have been disabled for this build definition. To enable these tests, edit this build definition and set the Disable Tests process parameter to false." />
+                                </If.Then>
+                              </If>
+                            </If.Else>
+                          </If>
+                        </Sequence>
+                      </ActivityAction>
+                    </ForEach>
+                    <If Condition="[BuildDetail.CompilationStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If CompilationStatus = Unknown" mtbwt:BuildTrackingParticipant.Importance="Low">
+                      <If.Then>
+                        <mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" DisplayName="Set CompilationStatus to Succeeded" PropertiesToSet="CompilationStatus" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                      </If.Then>
+                    </If>
+                    <If Condition="[BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If TestStatus = Unknown" mtbwt:BuildTrackingParticipant.Importance="Low">
+                      <If.Then>
+                        <mtbwa:SetBuildProperties DisplayName="Set TestStatus to Succeeded" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                      </If.Then>
+                    </If>
+                    <If Condition="[treatTestFailureAsBuildFailure And (BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed)]" DisplayName="If TreatTestFailureAsBuildFailure And (TestStatus = Failed)" mtbwt:BuildTrackingParticipant.Importance="Low">
+                      <If.Then>
+                        <mtbwa:SetBuildProperties DisplayName="Set Status to Failed" PropertiesToSet="Status" Status="[Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                      </If.Then>
+                    </If>
+                  </Sequence>
+                </TryCatch.Try>
+                <TryCatch.Catches>
+                  <Catch x:TypeArguments="s:Exception">
+                    <ActivityAction x:TypeArguments="s:Exception">
+                      <ActivityAction.Argument>
+                        <DelegateInArgument x:TypeArguments="s:Exception" Name="compilationExceptionArgument" />
+                      </ActivityAction.Argument>
+                      <Assign x:TypeArguments="s:Exception" DisplayName="Save the Compilation Exception" To="[compilationException]" Value="[compilationExceptionArgument]" mtbwt:BuildTrackingParticipant.Importance="None" />
+                    </ActivityAction>
+                  </Catch>
+                </TryCatch.Catches>
+              </TryCatch>
+              <If Condition="[AssociateChangesetsAndWorkItems]" DisplayName="If AssociateChangesetsAndWorkItems" mtbwt:BuildTrackingParticipant.Importance="Low">
+                <If.Then>
+                  <If Condition="[CreateLabel]" DisplayName="If CreateLabel and AssociateChangesetsAndWorkItems" mtbwt:BuildTrackingParticipant.Importance="Low">
+                    <If.Then>
+                      <mtbwa:InvokeForReason DisplayName="Associate Changesets and Work Items for non-Shelveset Builds" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
+                        <mtbwa:AssociateChangesetsAndWorkItems DisplayName="Associate Changesets and Work Items" Result="[associatedChangesets]" />
+                      </mtbwa:InvokeForReason>
+                    </If.Then>
+                    <If.Else>
+                      <mtbwa:WriteBuildWarning DisplayName="Write Associate Changesets and Work Items Warning" Message="Cannot Associate Changesets and Work Items because the Label Sources option is set to False." />
+                    </If.Else>
+                  </If>
+                </If.Then>
+              </If>
+            </Parallel>
+            <If Condition="[Not compilationException Is Nothing]" DisplayName="If a Compilation Exception Occurred" mtbwt:BuildTrackingParticipant.Importance="Low">
+              <If.Then>
+                <Throw DisplayName="Rethrow Compilation Exception" Exception="[compilationException]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+              </If.Then>
+            </If>
+            <Parallel DisplayName="Get Impacted Tests, Index Sources and Publish Symbols">
+              <If Condition="[PerformTestImpactAnalysis]" DisplayName="If PerformTestImpactAnalysis" mtbwt:BuildTrackingParticipant.Importance="Low">
+                <If.Then>
+                  <Sequence DisplayName="Get Impacted Tests" mtbwt:BuildTrackingParticipant.Importance="Low">
+                    <Sequence.Variables>
+                      <Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="assemblies" />
+                    </Sequence.Variables>
+                    <mtbwa:FindMatchingFiles DisplayName="Find Build Outputs" MatchPattern="[String.Format(&quot;{0}\**\*.dll;{0}\**\*.exe&quot;, BinariesDirectory)]" Result="[assemblies]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                    <mttbb:GetImpactedTests Assemblies="[assemblies]" AssociatedChangesets="[associatedChangesets]" BinariesRoot="[BinariesDirectory]" Build="[BuildDetail]" CodeChanges="{x:Null}" DisplayName="Get Impacted Tests" ImpactedTests="{x:Null}" Workspace="[Workspace]" />
+                  </Sequence>
+                </If.Then>
+              </If>
+              <If Condition="[SourceAndSymbolServerSettings.IndexSources Or SourceAndSymbolServerSettings.HasSymbolStorePath]" DisplayName="If SourceAndSymbolServerSettings.IndexSources Or SourceAndSymbolServerSettings.HasSymbolStorePath" mtbwt:BuildTrackingParticipant.Importance="Low">
+                <If.Then>
+                  <mtbwa:InvokeForReason DisplayName="Index Sources and Publish Symbols for Triggered Builds" Reason="Triggered">
+                    <mtbwa:InvokeForReason.Variables>
+                      <Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="symbolFiles" />
+                    </mtbwa:InvokeForReason.Variables>
+                    <mtbwa:FindMatchingFiles DisplayName="Find Symbol Files" MatchPattern="[String.Format(&quot;{0}\**\*.pdb&quot;, BinariesDirectory)]" Result="[symbolFiles]" mtbwt:BuildTrackingParticipant.Importance="Low" />
+                    <If Condition="[SourceAndSymbolServerSettings.IndexSources]" DisplayName="If SourceAndSymbolServerSettings.IndexSources" mtbwt:BuildTrackingParticipant.Importance="Low">
+                      <If.Then>
+                        <TryCatch DisplayName="Try Index Sources" mtbwt:BuildTrackingParticipant.Importance="Low">
+                          <TryCatch.Try>
+                            <mtbwa:IndexSources DisplayName="Index Sources" FileList="[symbolFiles]" />
+                          </TryCatch.Try>
+                          <TryCatch.Catches>
+                            <Catch x:TypeArguments="s:Exception">
+                              <ActivityAction x:TypeArguments="s:Exception">
+                                <ActivityAction.Argument>
+                                  <DelegateInArgument x:TypeArguments="s:Exception" Name="exception" />
+                                </ActivityAction.Argument>
+                                <mtbwa:WriteBuildError DisplayName="Write Indexing Sources Error" Message="[exception.Message]" />
+                              </ActivityAction>
+                            </Catch>
+                          </TryCatch.Catches>
+                        </TryCatch>
+                      </If.Then>
+                    </If>
+                    <If Condition="[SourceAndSymbolServerSettings.HasSymbolStorePath]" DisplayName="If SourceAndSymbolServerSettings.HasSymbolStorePath" mtbwt:BuildTrackingParticipant.Importance="Low">
+                      <If.Then>
+                        <TryCatch DisplayName="Try Publish Symbols" mtbwt:BuildTrackingParticipant.Importance="Low">
+                          <TryCatch.Try>
+                            <mtbwa:SharedResourceScope DisplayName="Synchronize Access to Symbol Store" MaxExecutionTime="[TimeSpan.Zero]" MaxWaitTime="[New TimeSpan(1, 0, 0)]" ResourceName="[SourceAndSymbolServerSettings.SymbolStorePath]" mtbwt:BuildTrackingParticipant.Importance="Low">
+                              <mtbwa:PublishSymbols DisplayName="Publish Symbols" FileList="[symbolFiles]" ProductName="[BuildDetail.BuildDefinition.Name]" StorePath="[SourceAndSymbolServerSettings.SymbolStorePath]" Version="[BuildDetail.BuildNumber]" />
+                            </mtbwa:SharedResourceScope>
+                          </TryCatch.Try>
+                          <TryCatch.Catches>
+                            <Catch x:TypeArguments="s:Exception">
+                              <ActivityAction x:TypeArguments="s:Exception">
+                                <ActivityAction.Argument>
+                                  <DelegateInArgument x:TypeArguments="s:Exception" Name="exception" />
+                                </ActivityAction.Argument>
+                                <mtbwa:WriteBuildError DisplayName="Write Publishing Symbols Error" Message="[exception.Message]" />
+                              </ActivityAction>
+                            </Catch>
+                          </TryCatch.Catches>
+                        </TryCatch>
+                      </If.Then>
+                    </If>
+                  </mtbwa:InvokeForReason>
+                </If.Then>
+              </If>
+            </Parallel>
+          </Sequence>
+        </TryCatch.Try>
+      </TryCatch>
+    </mtbwa:AgentScope>
+    <mtbwa:InvokeForReason DisplayName="Check In Gated Changes for CheckInShelveset Builds" Reason="CheckInShelveset">
+      <mtbwa:CheckInGatedChanges DisplayName="Check In Gated Changes" />
+    </mtbwa:InvokeForReason>
+  </Sequence>
+</Activity>

File diff suppressed because it is too large
+ 0 - 0
BuildProcessTemplates/LabDefaultTemplate.11.xaml


+ 76 - 0
BuildProcessTemplates/UpgradeTemplate.xaml

@@ -0,0 +1,76 @@
+<Activity mc:Ignorable="sad" x:Class="TfsBuild.Process" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mtbc="clr-namespace:Microsoft.TeamFoundation.Build.Client;assembly=Microsoft.TeamFoundation.Build.Client" xmlns:mtbw="clr-namespace:Microsoft.TeamFoundation.Build.Workflow;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwt="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Tracking;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtvc="clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:sad="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:sad1="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:this="clr-namespace:TfsBuild;" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+  <x:Members>
+    <x:Property Name="ConfigurationFolderPath" Type="InArgument(x:String)" />
+    <x:Property Name="AgentSettings" Type="InArgument(mtbwa:AgentSettings)" />
+    <x:Property Name="MSBuildArguments" Type="InArgument(x:String)" />
+    <x:Property Name="MSBuildPlatform" Type="InArgument(mtbwa:ToolPlatform)" />
+    <x:Property Name="DoNotDownloadBuildType" Type="InArgument(x:Boolean)" />
+    <x:Property Name="LogFilePerProject" Type="InArgument(x:Boolean)" />
+    <x:Property Name="SourcesSubdirectory" Type="InArgument(x:String)" />
+    <x:Property Name="BinariesSubdirectory" Type="InArgument(x:String)" />
+    <x:Property Name="TestResultsSubdirectory" Type="InArgument(x:String)" />
+    <x:Property Name="RecursionType" Type="InArgument(mtvc:RecursionType)" />
+    <x:Property Name="Verbosity" Type="InArgument(mtbw:BuildVerbosity)" />
+    <x:Property Name="Metadata" Type="mtbw:ProcessParameterMetadataCollection" />
+    <x:Property Name="SupportedReasons" Type="mtbc:BuildReason" />
+  </x:Members>
+  <this:Process.ConfigurationFolderPath>
+    <InArgument x:TypeArguments="x:String" />
+  </this:Process.ConfigurationFolderPath>
+  <this:Process.AgentSettings>[New Microsoft.TeamFoundation.Build.Workflow.Activities.AgentSettings() With {.MaxWaitTime = New System.TimeSpan(4, 0, 0), .MaxExecutionTime = New System.TimeSpan(0, 0, 0), .TagComparison = Microsoft.TeamFoundation.Build.Workflow.Activities.TagComparison.MatchExactly }]</this:Process.AgentSettings>
+  <this:Process.MSBuildArguments>
+    <InArgument x:TypeArguments="x:String" />
+  </this:Process.MSBuildArguments>
+  <this:Process.MSBuildPlatform>[Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto]</this:Process.MSBuildPlatform>
+  <this:Process.DoNotDownloadBuildType>[False]</this:Process.DoNotDownloadBuildType>
+  <this:Process.LogFilePerProject>[False]</this:Process.LogFilePerProject>
+  <this:Process.SourcesSubdirectory>
+    <InArgument x:TypeArguments="x:String" />
+  </this:Process.SourcesSubdirectory>
+  <this:Process.BinariesSubdirectory>
+    <InArgument x:TypeArguments="x:String" />
+  </this:Process.BinariesSubdirectory>
+  <this:Process.TestResultsSubdirectory>
+    <InArgument x:TypeArguments="x:String" />
+  </this:Process.TestResultsSubdirectory>
+  <this:Process.RecursionType>[Microsoft.TeamFoundation.VersionControl.Client.RecursionType.OneLevel]</this:Process.RecursionType>
+  <this:Process.Verbosity>[Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal]</this:Process.Verbosity>
+  <this:Process.Metadata>
+    <mtbw:ProcessParameterMetadataCollection />
+  </this:Process.Metadata>
+  <this:Process.SupportedReasons>All</this:Process.SupportedReasons>
+  <mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
+  <Sequence mtbwt:BuildTrackingParticipant.Importance="None">
+    <Sequence.Variables>
+      <Variable x:TypeArguments="mtbc:IBuildDetail" Name="BuildDetail" />
+    </Sequence.Variables>
+    <mtbwa:GetBuildDetail DisplayName="Get the Build" Result="[BuildDetail]" />
+    <mtbwa:InvokeForReason DisplayName="Update Build Number for Triggered Builds" Reason="Triggered">
+      <mtbwa:UpdateBuildNumber BuildNumberFormat="[&quot;$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r)&quot;]" DisplayName="Update Build Number" />
+    </mtbwa:InvokeForReason>
+    <mtbwa:AgentScope DisplayName="Run On Agent" MaxExecutionTime="[AgentSettings.MaxExecutionTime]" MaxWaitTime="[AgentSettings.MaxWaitTime]" ReservationSpec="[AgentSettings.GetAgentReservationSpec()]">
+      <mtbwa:AgentScope.Variables>
+        <Variable x:TypeArguments="x:String" Name="buildDirectory" />
+      </mtbwa:AgentScope.Variables>
+      <mtbwa:GetBuildDirectory DisplayName="Get the Build Directory" Result="[buildDirectory]" />
+      <If Condition="[Not String.IsNullOrEmpty(ConfigurationFolderPath)]" DisplayName="If Not String.IsNullOrEmpty(ConfigurationFolderPath)">
+        <If.Then>
+          <mtbwa:TfsBuild BinariesSubdirectory="[BinariesSubdirectory]" BuildDirectory="[buildDirectory]" CommandLineArguments="[MSBuildArguments]" ConfigurationFolderPath="[ConfigurationFolderPath]" DisplayName="Run TfsBuild for Configuration Folder" DoNotDownloadBuildType="[DoNotDownloadBuildType]" LogFilePerProject="[LogFilePerProject]" RecursionType="[RecursionType]" SourcesSubdirectory="[SourcesSubdirectory]" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" TestResultsSubdirectory="[TestResultsSubdirectory]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
+        </If.Then>
+      </If>
+      <If Condition="[BuildDetail.CompilationStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If CompilationStatus = Unknown">
+        <If.Then>
+           <mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" DisplayName="Set CompilationStatus to Succeeded" PropertiesToSet="CompilationStatus" />
+        </If.Then>
+      </If>
+      <If Condition="[BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If TestStatus = Unknown">
+        <If.Then>
+          <mtbwa:SetBuildProperties DisplayName="Set TestStatus to Succeeded" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" />
+        </If.Then>
+      </If>
+    </mtbwa:AgentScope>
+    <mtbwa:InvokeForReason Reason="CheckInShelveset">
+      <mtbwa:CheckInGatedChanges DisplayName="Check In Gated Changes" />
+    </mtbwa:InvokeForReason>
+  </Sequence>
+</Activity>

+ 1656 - 0
Doxyfile

@@ -0,0 +1,1656 @@
+# Doxyfile 1.7.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = libopc
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. The create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT                  = opc config/opc/config.h mce config/mce/config.h
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.vhd *.vhdl
+
+FILE_PATTERNS          =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH           = sample
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the stylesheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE               =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+#  will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [0,1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+# Note that a value of 0 will completely suppress the enum values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing
+# MathJax, but it is strongly recommended to install a local copy of MathJax
+# before deployment.
+
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML           = YES
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME           = FreeSans.ttf
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif.
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP            = YES

+ 12 - 0
LICENSE

@@ -0,0 +1,12 @@
+Copyright (c) 2010/2011, Florian Reuter
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+* Neither the name of Florian Reuter nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 84 - 0
Makefile.lib.xml

@@ -0,0 +1,84 @@
+<!--
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<project>
+  <library name="opc" dep="mce plib zlib xml" mode="c99">
+    <header root="config">
+      <file path="opc/config.h" install="yes"/>
+    </header>
+    <header root=".">
+      <file path="opc/opc.h" install="yes"/>
+      <file path="opc/container.h" install="yes"/>
+      <file path="opc/inputstream.h" install="yes"/>
+      <file path="opc/outputstream.h" install="yes"/>
+      <file path="opc/part.h" install="yes"/>
+      <file path="opc/relation.h" install="yes"/>
+      <file path="opc/xmlreader.h" install="yes"/>
+      <file path="opc/xmlwriter.h" install="yes"/>
+      <file path="opc/zip.h" install="yes"/>
+      <file path="opc/helper.h" install="yes"/>
+      <file path="opc/file.h" install="yes"/>
+      <file path="opc/properties.h" install="yes"/>
+    </header>
+    <header root="opc">
+      <file path="internal.h"/>
+    </header>
+    <source root="opc">
+      <file path="opc.c"/>
+      <file path="container.c"/>
+      <file path="inputstream.c"/>
+      <file path="outputstream.c"/>
+      <file path="part.c"/>
+      <file path="relation.c"/>
+      <file path="xmlreader.c"/>
+      <file path="xmlwriter.c"/>
+      <file path="zip.c"/>
+      <file path="helper.c"/>
+      <file path="file.c"/>
+      <file path="properties.c"/>
+    </source>
+  </library>
+  <library name="mce" dep="plib xml" mode="c99">
+    <header root="config">
+      <file path="mce/config.h" install="yes"/>
+    </header>
+    <header root=".">
+      <file path="mce/textreader.h" install="yes"/>
+      <file path="mce/textwriter.h" install="yes"/>
+      <file path="mce/helper.h" install="yes"/>
+    </header>
+    <source root="mce">
+      <file path="textreader.c"/>
+      <file path="textwriter.c"/>
+      <file path="helper.c"/>
+    </source>
+  </library>
+</project>

+ 97 - 0
Makefile.platform.xml

@@ -0,0 +1,97 @@
+<!--
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<project>
+  <platform name="*-debug-gcc-*" 
+            cc="gcc"
+            ar="ar"
+            ld="ld"
+            cflags="-g -fno-exceptions -Wall -ansi -pedantic"
+            cflags_c="-std=gnu99" 
+            cflags_cpp="-fno-rtti"
+            cppflags=""/>
+  <platform name="*-release-gcc-*" 
+            cc="gcc"
+            ar="ar"
+            ld="ld"
+            cflags="-O3 -fno-exceptions -Wall -ansi -pedantic"
+            cflags_c="-std=gnu99" 
+            cflags_cpp="-fno-rtti"
+            cppflags=""/>
+  <platform name="darwin-debug-gcc-*" 
+            cc="gcc"
+            ar="ar"
+            ld="ld"
+            cflags="-g -fno-exceptions"
+            cflags_c="-std=c99" 
+            cflags_cpp="-fno-rtti"
+            cppflags="-arch x86_64"/>
+  <platform name="darwin-release-gcc-*" 
+            cc="gcc"
+            ar="ar"
+            ld="ld"
+            cflags="-O3 -fno-exceptions"
+            cflags_c="-std=c99" 
+            cflags_cpp="-fno-rtti"
+            cppflags="-arch x86_64"/>
+  <platform name="*-debug-clang-*" 
+            cc="clang"
+            ar="ar"
+            ld="ld"
+            cflags="-g -fno-exceptions"
+            cflags_c="-std=c99" 
+            cflags_cpp="-fno-rtti"
+            cppflags=""/>
+  <platform name="ios4-debug-gcc-*"	
+            cc="/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2"
+            ar="/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ar"
+            ld="/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ld"
+            cflags="-g -arch i386 -fno-exceptions"
+            cflags_c="-std=c99" cflags_cpp="-fno-rtti"
+            cppflags="-D__IPHONE_OS_VERSION_MIN_REQUIRED=30200 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.0.sdk"
+            host="i386-apple-darwin10" />
+  <platform name="ios4-release-gcc-*"	
+            cc="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2"
+            ar="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar"
+            ld="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld"
+            cflags="-g -arch armv6 -fno-exceptions"
+            cflags_c="-std=c99" cflags_cpp="-fno-rtti"
+            cppflags="-D__IPHONE_OS_VERSION_MIN_REQUIRED=30200 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.2.sdk" 
+            host="arm-apple-darwin10"/>
+  <platform name="android9-debug-gcc-*"	
+            cc="/Users/flr/Documents/tmp/android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gcc"
+            ar="/Users/flr/Documents/tmp/android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-ar"
+            ld="/Users/flr/Documents/tmp/android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-ld"
+            cppflags="--sysroot /Users/flr/Documents/tmp/android-ndk-r5/platforms/android-9/arch-arm"
+            cflags="-fno-exceptions -mthumb"
+            cflags_c="-std=c99" cflags_cpp="-fno-rtti" 
+            host="arm-android-linux" />
+</project>

+ 38 - 0
Makefile.xml

@@ -0,0 +1,38 @@
+<!--
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<project>
+  <include path="Makefile.platform.xml"/>
+  <include path="third_party/Makefile.xml"/>
+  <include path="plib/Makefile.xml"/>
+  <include path="Makefile.lib.xml"/>
+  <include path="sample/Makefile.xml"/>
+</project>

+ 32 - 0
README

@@ -0,0 +1,32 @@
+
+BUILD ON LINUX/MAC OSX:
+./configure
+make
+
+BUILD on LINUX with system libs:
+./configure --with-zlib=yes --with-zlib-ldflags="`pkg-config zlib --libs`" --with-libxml=yes --with-libxml-cppflags="`pkg-config libxml-2.0 --cflags`" --with-libxml-ldflags="`pkg-config libxml-2.0 --libs`"
+
+BUILD ON WINDOWS:
+* Optionally generate project files: c:\Python26\python.exe generate.py --include Makefile.xml win32-*-msvc-*
+* Open win32\solution.sln in Visual Studio.
+
+RELASE in a ZIP file (win32):
+c:\Python26\python.exe generate.py --include Makefile.xml --package libopc-sdk-0.0.1.zip win32-release-msvc 
+
+
+RELASE in a ZIP file (MaxOSX):
+python generate.py --include Makefile.xml --package libopc-sdk-0.0.1.zip --config-dir=build/config  darwin-release-gcc
+
+PACKAGE LINUX
+./generate.py --with-zlib=yes --with-zlib-ldflags="`pkg-config zlib --libs`" --with-libxml=yes --with-libxml-cppflags="`pkg-config libxml-2.0 --cflags`" --with-libxml-ldflags="`pkg-config libxml-2.0 --libs`" --package usr.zip --config-dir=build --include Makefile.xml  linux-debug-gcc-i686
+
+PACKAGE DEBIAN [http://www.debian.org/doc/manuals/maint-guide/index.en.html]
+1) Adjust config/libopc.pc VERSION
+   Adjust debian/changelog
+2) ./configure --with-zlib=yes --with-zlib-ldflags="`pkg-config zlib --libs`" --with-libxml=yes --with-libxml-cppflags="`pkg-config libxml-2.0 --cflags`" --with-libxml-ldflags="`pkg-config libxml-2.0 --libs`" --arch=any
+DESTDIR=`pwd`/build/linux-debug-gcc-any/install make install
+3) dpkg-buildpackage
+or 
+3b) dpkg-buildpackage -B
+4) lintian -i -I --show-overrides ../libopc_0.0.2_i386.changes  | less
+

+ 14 - 0
config/libopc.pc

@@ -0,0 +1,14 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+modules=1
+
+Name: libopc
+Version: 0.0.2
+Description: LIBOPC
+Requires:
+Libs: -L${libdir} -lopc -lmce -lplib
+Libs.private:  -lxml2 -lz -lm  
+Cflags: -I${includedir}
+

+ 53 - 0
config/mce/config.h

@@ -0,0 +1,53 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**@file config/mce/config.h
+ */
+#ifndef MCE_CONFIG_H
+#define MCE_CONFIG_H
+
+#include <libxml/xmlstring.h>
+#include <stdio.h>
+#include <plib/plib.h>
+#include <assert.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MCE_NAMESPACE_SUBSUMPTION_ENABLED 0
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif  
+
+#endif /* MCE_CONFIG_H */

+ 189 - 0
config/opc/config.h

@@ -0,0 +1,189 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**@file config/opc/config.h
+ */
+#ifndef OPC_CONFIG_H
+#define OPC_CONFIG_H
+
+#include <libxml/xmlstring.h>
+#include <plib/plib.h>
+#include <assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif   
+
+
+/**
+  Assert expression e is true. Will be removed entirely in release mode.
+  \hideinitializer
+ */
+#define OPC_ASSERT(e) assert(e)
+
+/**
+  Assert expression e is true. Expression will be executed in release mode too.
+  \hideinitializer
+ */
+#ifdef NDEBUG
+#define OPC_ENSURE(e) (void)(e)
+#else
+#define OPC_ENSURE(e) assert(e)
+#endif
+
+
+/**
+  Constant for boolean true.
+  \hideinitializer
+ */
+#define OPC_TRUE (0==0)
+
+/**
+  Constant for boolean false.
+  \hideinitializer
+ */
+#define OPC_FALSE (0==1)
+
+    /** 
+      Boolean type.
+      \hideinitializer
+      */
+    typedef pbool_t opc_bool_t;
+
+    /** 
+      Type which represents an offset in e.g. a file.
+      \hideinitializer
+      */
+    typedef pofs_t opc_ofs_t;
+
+    /** 
+      8-bit unsigned integer.
+      \hideinitializer
+      */
+    typedef puint8_t opc_uint8_t;
+
+    /** 
+      16-bit unsigned integer.
+      \hideinitializer
+      */
+    typedef puint16_t opc_uint16_t;
+
+    /** 
+      32-bit unsigned integer.
+      \hideinitializer
+      */
+    typedef puint32_t opc_uint32_t;
+
+    /** 
+      64-bit unsigned integer.
+      \hideinitializer
+      */
+    typedef puint64_t opc_uint64_t;
+
+    /** 
+      8-bit signed integer.
+      \hideinitializer
+      */
+    typedef pint8_t opc_int8_t;
+
+    /** 
+      16-bit signed integer.
+      \hideinitializer
+      */
+    typedef pint16_t opc_int16_t;
+
+    /** 
+      32-bit signed integer.
+      \hideinitializer
+      */
+    typedef pint32_t opc_int32_t;
+
+    /** 
+      64-bit signed integer.
+      \hideinitializer
+      */
+    typedef pint64_t opc_int64_t;
+
+/**
+  Default size fo the deflate buffer used by zlib.
+  */
+#define OPC_DEFLATE_BUFFER_SIZE 4096
+
+/**
+  Max system path len.
+  */
+#define OPC_MAX_PATH 512
+
+    /**
+      Error codes for the OPC module.
+      */
+    typedef enum OPC_ERROR_ENUM {
+        OPC_ERROR_NONE,
+        OPC_ERROR_STREAM,
+        OPC_ERROR_SEEK, // can't seek
+        OPC_ERROR_UNSUPPORTED_DATA_DESCRIPTOR,
+        OPC_ERROR_UNSUPPORTED_COMPRESSION,
+        OPC_ERROR_DEFLATE,
+        OPC_ERROR_HEADER,
+        OPC_ERROR_MEMORY,
+        OPC_ERROR_XML, 
+        OPC_ERROR_USER // user triggered an abort
+    } opc_error_t;
+    
+    /**
+      Compression options for OPC streams.
+      */
+    typedef enum OPC_COMPRESSIONOPTION_ENUM {
+        OPC_COMPRESSIONOPTION_NONE,
+        OPC_COMPRESSIONOPTION_NORMAL,
+        OPC_COMPRESSIONOPTION_MAXIMUM,
+        OPC_COMPRESSIONOPTION_FAST,
+        OPC_COMPRESSIONOPTION_SUPERFAST
+    } opcCompressionOption_t;
+
+
+/**
+  Helper for debug logs.
+  \hideinitializer
+  */
+#define opc_logf printf
+
+/**
+  Abstraction for memset(m, 0, s).
+  \hideinitializer
+ */
+#define opc_bzero_mem(m,s) memset(m, 0, s)
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif  
+
+#endif /* OPC_CONFIG_H */

+ 1 - 0
config/win32-msvc/libxml2-2.7.7/..svnbridge/config.h

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 124 - 0
config/win32-msvc/libxml2-2.7.7/config.h

@@ -0,0 +1,124 @@
+#ifndef __LIBXML_WIN32_CONFIG__
+#define __LIBXML_WIN32_CONFIG__
+
+#define HAVE_CTYPE_H
+#define HAVE_STDARG_H
+#define HAVE_MALLOC_H
+#define HAVE_ERRNO_H
+
+#if defined(_WIN32_WCE)
+#undef HAVE_ERRNO_H
+#include <windows.h>
+#include "wincecompat.h"
+#else
+#define HAVE_SYS_STAT_H
+#define HAVE__STAT
+#define HAVE_STAT
+#define HAVE_STDLIB_H
+#define HAVE_TIME_H
+#define HAVE_FCNTL_H
+#include <io.h>
+#include <direct.h>
+#endif
+
+#include <libxml/xmlversion.h>
+
+#ifndef ICONV_CONST
+#define ICONV_CONST const
+#endif
+
+#ifdef NEED_SOCKETS
+#include <wsockcompat.h>
+#endif
+
+/*
+ * Windows platforms may define except 
+ */
+#undef except
+
+#define HAVE_ISINF
+#define HAVE_ISNAN
+#include <math.h>
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+/* MS C-runtime has functions which can be used in order to determine if
+   a given floating-point variable contains NaN, (+-)INF. These are 
+   preferred, because floating-point technology is considered propriatary
+   by MS and we can assume that their functions know more about their 
+   oddities than we do. */
+#include <float.h>
+/* Bjorn Reese figured a quite nice construct for isinf() using the _fpclass
+   function. */
+#ifndef isinf
+#define isinf(d) ((_fpclass(d) == _FPCLASS_PINF) ? 1 \
+	: ((_fpclass(d) == _FPCLASS_NINF) ? -1 : 0))
+#endif
+/* _isnan(x) returns nonzero if (x == NaN) and zero otherwise. */
+#ifndef isnan
+#define isnan(d) (_isnan(d))
+#endif
+#else /* _MSC_VER */
+#ifndef isinf
+static int isinf (double d) {
+    int expon = 0;
+    double val = frexp (d, &expon);
+    if (expon == 1025) {
+        if (val == 0.5) {
+            return 1;
+        } else if (val == -0.5) {
+            return -1;
+        } else {
+            return 0;
+        }
+    } else {
+        return 0;
+    }
+}
+#endif
+#ifndef isnan
+static int isnan (double d) {
+    int expon = 0;
+    double val = frexp (d, &expon);
+    if (expon == 1025) {
+        if (val == 0.5) {
+            return 0;
+        } else if (val == -0.5) {
+            return 0;
+        } else {
+            return 1;
+        }
+    } else {
+        return 0;
+    }
+}
+#endif
+#endif /* _MSC_VER */
+
+#if defined(_MSC_VER)
+#define mkdir(p,m) _mkdir(p)
+#define snprintf _snprintf
+#if _MSC_VER < 1500
+#define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
+#endif
+#elif defined(__MINGW32__)
+#define mkdir(p,m) _mkdir(p)
+#endif
+
+/* Threading API to use should be specified here for compatibility reasons.
+   This is however best specified on the compiler's command-line. */
+#if defined(LIBXML_THREAD_ENABLED)
+#if !defined(HAVE_PTHREAD_H) && !defined(HAVE_WIN32_THREADS) && !defined(_WIN32_WCE)
+#define HAVE_WIN32_THREADS
+#endif
+#endif
+
+/* Some third-party libraries far from our control assume the following
+   is defined, which it is not if we don't include windows.h. */
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+#if !defined(TRUE)
+#define TRUE (!(FALSE))
+#endif
+
+#endif /* __LIBXML_WIN32_CONFIG__ */
+

+ 1 - 0
config/win32-msvc/libxml2-2.7.7/libxml/..svnbridge/xmlversion.h

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 458 - 0
config/win32-msvc/libxml2-2.7.7/libxml/xmlversion.h

@@ -0,0 +1,458 @@
+/*
+ * Summary: compile-time version informations
+ * Description: compile-time version informations for the XML library
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_VERSION_H__
+#define __XML_VERSION_H__
+
+#include <libxml/xmlexports.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * use those to be sure nothing nasty will happen if
+ * your library and includes mismatch
+ */
+#ifndef LIBXML2_COMPILING_MSCCDEF
+XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
+#endif /* LIBXML2_COMPILING_MSCCDEF */
+
+/**
+ * LIBXML_DOTTED_VERSION:
+ *
+ * the version string like "1.2.3"
+ */
+#define LIBXML_DOTTED_VERSION "2.7.7"
+
+/**
+ * LIBXML_VERSION:
+ *
+ * the version number: 1.2.3 value is 10203
+ */
+#define LIBXML_VERSION 20707
+
+/**
+ * LIBXML_VERSION_STRING:
+ *
+ * the version number string, 1.2.3 value is "10203"
+ */
+#define LIBXML_VERSION_STRING "20707"
+
+/**
+ * LIBXML_VERSION_EXTRA:
+ *
+ * extra version information, used to show a CVS compilation
+ */
+#define LIBXML_VERSION_EXTRA "-SVN2048"
+
+/**
+ * LIBXML_TEST_VERSION:
+ *
+ * Macro to check that the libxml version in use is compatible with
+ * the version the software has been compiled against
+ */
+#define LIBXML_TEST_VERSION xmlCheckVersion(20707);
+
+#ifndef VMS
+#if 0
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO
+#else
+/**
+ * WITHOUT_TRIO:
+ *
+ * defined if the trio support should not be configured in
+ */
+#define WITHOUT_TRIO
+#endif
+#else /* VMS */
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO 1
+#endif /* VMS */
+
+/**
+ * LIBXML_THREAD_ENABLED:
+ *
+ * Whether the thread support is configured in
+ */
+#if 0
+#if defined(_REENTRANT) || defined(__MT__) || \
+    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
+#define LIBXML_THREAD_ENABLED
+#endif
+#endif
+
+/**
+ * LIBXML_TREE_ENABLED:
+ *
+ * Whether the DOM like tree manipulation API support is configured in
+ */
+#if 0
+#define LIBXML_TREE_ENABLED
+#endif
+
+/**
+ * LIBXML_OUTPUT_ENABLED:
+ *
+ * Whether the serialization/saving support is configured in
+ */
+#if 1
+#define LIBXML_OUTPUT_ENABLED
+#endif
+
+/**
+ * LIBXML_PUSH_ENABLED:
+ *
+ * Whether the push parsing interfaces are configured in
+ */
+#if 1
+#define LIBXML_PUSH_ENABLED
+#endif
+
+/**
+ * LIBXML_READER_ENABLED:
+ *
+ * Whether the xmlReader parsing interface is configured in
+ */
+#if 1
+#define LIBXML_READER_ENABLED
+#endif
+
+/**
+ * LIBXML_PATTERN_ENABLED:
+ *
+ * Whether the xmlPattern node selection interface is configured in
+ */
+#if 0
+#define LIBXML_PATTERN_ENABLED
+#endif
+
+/**
+ * LIBXML_WRITER_ENABLED:
+ *
+ * Whether the xmlWriter saving interface is configured in
+ */
+#if 1
+#define LIBXML_WRITER_ENABLED
+#endif
+
+/**
+ * LIBXML_SAX1_ENABLED:
+ *
+ * Whether the older SAX1 interface is configured in
+ */
+#if 0
+#define LIBXML_SAX1_ENABLED
+#endif
+
+/**
+ * LIBXML_FTP_ENABLED:
+ *
+ * Whether the FTP support is configured in
+ */
+#if 0
+#define LIBXML_FTP_ENABLED
+#endif
+
+/**
+ * LIBXML_HTTP_ENABLED:
+ *
+ * Whether the HTTP support is configured in
+ */
+#if 0
+#define LIBXML_HTTP_ENABLED
+#endif
+
+/**
+ * LIBXML_VALID_ENABLED:
+ *
+ * Whether the DTD validation support is configured in
+ */
+#if 0
+#define LIBXML_VALID_ENABLED
+#endif
+
+/**
+ * LIBXML_HTML_ENABLED:
+ *
+ * Whether the HTML support is configured in
+ */
+#if 0
+#define LIBXML_HTML_ENABLED
+#endif
+
+/**
+ * LIBXML_LEGACY_ENABLED:
+ *
+ * Whether the deprecated APIs are compiled in for compatibility
+ */
+#if 0
+#define LIBXML_LEGACY_ENABLED
+#endif
+
+/**
+ * LIBXML_C14N_ENABLED:
+ *
+ * Whether the Canonicalization support is configured in
+ */
+#if 0
+#define LIBXML_C14N_ENABLED
+#endif
+
+/**
+ * LIBXML_CATALOG_ENABLED:
+ *
+ * Whether the Catalog support is configured in
+ */
+#if 0
+#define LIBXML_CATALOG_ENABLED
+#endif
+
+/**
+ * LIBXML_DOCB_ENABLED:
+ *
+ * Whether the SGML Docbook support is configured in
+ */
+#if 0
+#define LIBXML_DOCB_ENABLED
+#endif
+
+/**
+ * LIBXML_XPATH_ENABLED:
+ *
+ * Whether XPath is configured in
+ */
+#if 0
+#define LIBXML_XPATH_ENABLED
+#endif
+
+/**
+ * LIBXML_XPTR_ENABLED:
+ *
+ * Whether XPointer is configured in
+ */
+#if 0
+#define LIBXML_XPTR_ENABLED
+#endif
+
+/**
+ * LIBXML_XINCLUDE_ENABLED:
+ *
+ * Whether XInclude is configured in
+ */
+#if 0
+#define LIBXML_XINCLUDE_ENABLED
+#endif
+
+/**
+ * LIBXML_ICONV_ENABLED:
+ *
+ * Whether iconv support is available
+ */
+#if 0
+#define LIBXML_ICONV_ENABLED
+#endif
+
+/**
+ * LIBXML_ISO8859X_ENABLED:
+ *
+ * Whether ISO-8859-* support is made available in case iconv is not
+ */
+#if 0
+#define LIBXML_ISO8859X_ENABLED
+#endif
+
+/**
+ * LIBXML_DEBUG_ENABLED:
+ *
+ * Whether Debugging module is configured in
+ */
+#if 1
+#define LIBXML_DEBUG_ENABLED
+#endif
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * Whether the memory debugging is configured in
+ */
+#if 0
+#define DEBUG_MEMORY_LOCATION
+#endif
+
+/**
+ * LIBXML_DEBUG_RUNTIME:
+ *
+ * Whether the runtime debugging is configured in
+ */
+#if 0
+#define LIBXML_DEBUG_RUNTIME
+#endif
+
+/**
+ * LIBXML_UNICODE_ENABLED:
+ *
+ * Whether the Unicode related interfaces are compiled in
+ */
+#if 0
+#define LIBXML_UNICODE_ENABLED
+#endif
+
+/**
+ * LIBXML_REGEXP_ENABLED:
+ *
+ * Whether the regular expressions interfaces are compiled in
+ */
+#if 0
+#define LIBXML_REGEXP_ENABLED
+#endif
+
+/**
+ * LIBXML_AUTOMATA_ENABLED:
+ *
+ * Whether the automata interfaces are compiled in
+ */
+#if 0
+#define LIBXML_AUTOMATA_ENABLED
+#endif
+
+/**
+ * LIBXML_EXPR_ENABLED:
+ *
+ * Whether the formal expressions interfaces are compiled in
+ */
+#if 0
+#define LIBXML_EXPR_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMAS_ENABLED:
+ *
+ * Whether the Schemas validation interfaces are compiled in
+ */
+#if 0
+#define LIBXML_SCHEMAS_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMATRON_ENABLED:
+ *
+ * Whether the Schematron validation interfaces are compiled in
+ */
+#if 0
+#define LIBXML_SCHEMATRON_ENABLED
+#endif
+
+/**
+ * LIBXML_MODULES_ENABLED:
+ *
+ * Whether the module interfaces are compiled in
+ */
+#if 0
+#define LIBXML_MODULES_ENABLED
+/**
+ * LIBXML_MODULE_EXTENSION:
+ *
+ * the string suffix used by dynamic modules (usually shared libraries)
+ */
+#define LIBXML_MODULE_EXTENSION "" 
+#endif
+
+/**
+ * LIBXML_ZLIB_ENABLED:
+ *
+ * Whether the Zlib support is compiled in
+ */
+#if 0
+#define LIBXML_ZLIB_ENABLED
+#endif
+
+#ifdef __GNUC__
+#ifdef HAVE_ANSIDECL_H
+#include <ansidecl.h>
+#endif
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__((unused))
+#endif
+
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+
+#ifndef LIBXML_ATTR_ALLOC_SIZE
+# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+# else
+#  define LIBXML_ATTR_ALLOC_SIZE(x)
+# endif
+#else
+# define LIBXML_ATTR_ALLOC_SIZE(x)
+#endif
+
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+
+#ifndef LIBXML_ATTR_FORMAT
+# if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
+# else
+#  define LIBXML_ATTR_FORMAT(fmt,args)
+# endif
+#else
+# define LIBXML_ATTR_FORMAT(fmt,args)
+#endif
+
+#else /* ! __GNUC__ */
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+#define ATTRIBUTE_UNUSED
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+#define LIBXML_ATTR_ALLOC_SIZE(x)
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+#define LIBXML_ATTR_FORMAT(fmt,args)
+#endif /* __GNUC__ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
+
+

+ 1 - 0
config/win32-msvc/zlib-1.2.5/..svnbridge/zconf.h

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 428 - 0
config/win32-msvc/zlib-1.2.5/zconf.h

@@ -0,0 +1,428 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+
+/* all linked symbols */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define compress              z_compress
+#  define compress2             z_compress2
+#  define compressBound         z_compressBound
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  define gz_error              z_gz_error
+#  define gz_intmax             z_gz_intmax
+#  define gz_strwinerror        z_gz_strwinerror
+#  define gzbuffer              z_gzbuffer
+#  define gzclearerr            z_gzclearerr
+#  define gzclose               z_gzclose
+#  define gzclose_r             z_gzclose_r
+#  define gzclose_w             z_gzclose_w
+#  define gzdirect              z_gzdirect
+#  define gzdopen               z_gzdopen
+#  define gzeof                 z_gzeof
+#  define gzerror               z_gzerror
+#  define gzflush               z_gzflush
+#  define gzgetc                z_gzgetc
+#  define gzgets                z_gzgets
+#  define gzoffset              z_gzoffset
+#  define gzoffset64            z_gzoffset64
+#  define gzopen                z_gzopen
+#  define gzopen64              z_gzopen64
+#  define gzprintf              z_gzprintf
+#  define gzputc                z_gzputc
+#  define gzputs                z_gzputs
+#  define gzread                z_gzread
+#  define gzrewind              z_gzrewind
+#  define gzseek                z_gzseek
+#  define gzseek64              z_gzseek64
+#  define gzsetparams           z_gzsetparams
+#  define gztell                z_gztell
+#  define gztell64              z_gztell64
+#  define gzungetc              z_gzungetc
+#  define gzwrite               z_gzwrite
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  define uncompress            z_uncompress
+#  define zError                z_zError
+#  define zcalloc               z_zcalloc
+#  define zcfree                z_zcfree
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  define gzFile                z_gzFile
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef STDC
+#  include <sys/types.h>    /* for off_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#  include <unistd.h>       /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>     /* for off_t */
+#  endif
+#  ifndef z_off_t
+#    define z_off_t off_t
+#  endif
+#endif
+
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define z_off64_t off64_t
+#else
+#  define z_off64_t z_off_t
+#endif
+
+#if defined(__OS400__)
+#  define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */

+ 174 - 0
configure

@@ -0,0 +1,174 @@
+#! /bin/bash
+
+OS=`uname -s | tr '[:upper:]' '[:lower:]'`
+ARCH=`uname -p`
+TARGET=debug
+TOOLCHAIN=gcc
+HOST=""
+EXTERNAL_ZLIB="no"
+EXTERNAL_ZLIB_CPPFLAGS=""
+EXTERNAL_ZLIB_LDFLAGS=""
+EXTERNAL_LIBXML="no"
+EXTERNAL_LIBXML_CPPFLAGS=""
+EXTERNAL_LIBXML_LDFLAGS=""
+
+
+while test $# -ge 1
+do
+case "$1" in
+	-h* | --help)
+		echo 'usage:'
+		echo ' configure [--with-python="PATH TO PYTHON EXECUTABLE"]'
+         echo '           [--platform="OS-TARGET-TOOLCHAIN", e.g. --platform="linux-debug-gcc-i386"]'
+         echo '           [--os="OS", e.g. --os="linux"]'
+         echo '           [--target="TARGET", e.g. --target="release"]'
+         echo '           [--toolchain="TOOLCHAIN", e.g. --toolchain="clang"]'
+         echo '           [--arch="ARCH", e.g. --arch="i386"]'
+		exit 0 ;;
+	--with-python=*) PYTHON_PATH=`echo $1 | sed 's/.*=//'`; shift ;;
+	--platform=*) PLATFORM=`echo $1 | sed 's/.*=//'`; shift ;;
+	--target=*) TARGET=`echo $1 | sed 's/.*=//'`; shift ;;
+	--toolchain=*) TOOLCHAIN=`echo $1 | sed 's/.*=//'`; shift ;;
+	--os=*) OS=`echo $1 | sed 's/.*=//'`; shift ;;
+	--arch=*) ARCH=`echo $1 | sed 's/.*=//'`; shift ;;
+	--with-zlib=*) EXTERNAL_ZLIB=`echo $1 | sed 's/.*=//'`; shift ;;
+	--with-zlib-cppflags=*) EXTERNAL_ZLIB_CPPFLAGS=`echo $1 | sed 's/.*=//'`; shift ;;
+	--with-zlib-ldflags=*) EXTERNAL_ZLIB_LDFLAGS=`echo $1 | sed 's/.*=//'`; shift ;;
+	--with-libxml=*) EXTERNAL_LIBXML=`echo $1 | sed 's/.*=//'`; shift ;;
+	--with-libxml-cppflags=*) EXTERNAL_LIBXML_CPPFLAGS=`echo $1 | sed 's/.*=//'`; shift ;;
+	--with-libxml-ldflags=*) EXTERNAL_LIBXML_LDFLAGS=`echo $1 | sed 's/.*=//'`; shift ;;
+	*) echo "unknown option: $1"; echo "$0 --help for help"; exit 1 ;;
+esac
+done
+
+BUILDDIR="build"
+
+PLIBCONFIG=""
+PLIBFILES="include/plib/plib.h=>%PACKAGE%/config/%PLATFORM%/plib/include/plib/"
+
+ZLIBCONFIG=""
+ZLIBFILES="zconf.h=>config/%PLATFORM%/%PACKAGE%/"
+LIBXMLCONFIG="--without-c14n \
+--without-catalog \
+--without-docbook  \
+--without-fexceptions \
+--without-ftp \
+--without-history  \
+--without-html \
+--without-http \
+--without-iconv \
+--without-iso8859x \
+--without-legacy \
+--without-output \
+--without-pattern \
+--without-push \
+--without-python \
+--with-reader \
+--without-regexps \
+--without-sax1 \
+--without-schemas \
+--without-schematron \
+--without-threads \
+--without-tree \
+--without-valid \
+--with-writer \
+--without-xinclude \
+--without-xpath \
+--without-xptr \
+--without-modules \
+--without-zlib"
+LIBXMLFILES="config.h=>config/%PLATFORM%/%PACKAGE%/ include/libxml/xmlversion.h=>config/%PLATFORM%/%PACKAGE%/libxml"
+
+execConfigure() {
+	RET=0
+	SRCDIR=$1
+	PACKAGE=$2
+	OPTIONS=$3
+	FILES=$4
+	OPT_HOST=$5
+	echo "Configuring $SRCDIR/$PACKAGE"
+	mkdir -p "$BUILDDIR/copy"
+	rm -rf "$BUILDDIR/copy/$PACKAGE"
+	rm -rf "$BUILDDIR/$PLATFORM/$PACKAGE"
+	cp -r "$SRCDIR/$PACKAGE" "$BUILDDIR/copy/$PACKAGE"
+	if [ -d "$BUILDDIR/copy/$PACKAGE" ]; then
+		pushd "$BUILDDIR/copy/$PACKAGE" > /dev/null
+		if [ -x "./configure" ]; then
+			./configure $OPT_HOST $OPTIONS
+			if [ $? -ne 0 ]; then
+				popd -n > /dev/null
+				echo "*** error running \"./configure $OPT_HOST $OPTIONS\" in \"$BUILDDIR/$PACKAGE\""
+				echo "*** please fix this first!"
+				exit 1
+			fi
+		else
+			echo "configure not found in directory \"$BUILDDIR/$PACKAGE\""
+		fi
+		popd > /dev/null
+
+		PAIR=$FILES
+		for PAIR in $FILES; do
+			FILE=(${PAIR/=>/ })
+			SRCFILE="$BUILDDIR/copy/$PACKAGE/${FILE[0]}"
+			if [ ! -f "$SRCFILE" ]; then
+				echo "*** file \"$SRCFILE\" in has not been generated by configure."
+				exit 1
+			fi
+			TARGETDIR="$BUILDDIR/${FILE[1]}"
+			TARGETDIR=${TARGETDIR/\%PLATFORM\%/$PLATFORM}
+			TARGETDIR=${TARGETDIR/\%PACKAGE\%/$PACKAGE}
+			mkdir -p "$TARGETDIR"
+			cp "$SRCFILE" "$TARGETDIR"
+			TARGETFILE="$TARGETDIR/`basename ${FILE[0]}`"
+			if [ ! -f "$TARGETFILE" ]; then
+				echo "*** file "$SRCFILE" could not be copied to "$TARGETFILE" (either directory could not be created or copy failed)"
+				exit 1
+			fi
+		done
+	else
+		echo "could not create temporary copy of \"$SRCDIR/$PACKAGE\" in \"$BUILDDIR/copy/$PACKAGE\""
+	fi
+	rm -rf "$BUILDDIR/copy/$PACKAGE"
+}
+
+if [ x$PLATFORM = x ]; then 
+	PLATFORM="$OS-$TARGET-$TOOLCHAIN-$ARCH"
+fi
+#if [ x$CC = x ]; then
+#	CC=${PLATFORM##*-}
+#fi
+#export CC
+if [ x$PYTHON_PATH = x ]; then 
+	PYTHON_PATH=python
+fi
+
+if [[ $PLATFORM =~ ^[^-]+-[^-]+-[^-]+-[^-]+$ ]]; then
+	PYTHON_VERSION="`$PYTHON_PATH -V 2>&1`"
+	if [[ $PYTHON_VERSION =~ ^"Python 2.6."[1-9][0-9]*$|^"Python 2."[7-9][0-9]*(\.[0-9]*(\+)?)?$|^"Python "[3][0-9]*(\.[0-9]*(\.[0-9]*)(\+)?)?$ ]]; then
+		FLAGS=`$PYTHON_PATH generate.py --include Makefile.platform.xml --config-dir $BUILDDIR --with-zlib=$EXTERNAL_ZLIB --with-zlib-cppflags="$EXTERNAL_ZLIB_CPPFLAGS" --with-zlib-ldflags="$EXTERNAL_ZLIB_LDFLAGS" --with-libxml=$EXTERNAL_LIBXML --with-libxml-cppflags="$EXTERNAL_LIBXML_CPPFLAGS" --with-libxml-ldflags="$EXTERNAL_LIBXML_LDFLAGS" --print-env $PLATFORM`
+		eval $FLAGS
+		CONFIG_OPT=""
+		if [ x"" != x$HOST ]; then
+			CONFIG_OPT="--host=$HOST"
+		fi
+		execConfigure "." "plib" "$PLIBCONFIG" "$PLIBFILES" "$CONFIG_OPT"
+		if [ x"no" == x$EXTERNAL_ZLIB ]; then 
+			execConfigure "third_party" "zlib-1.2.5" "$ZLIBCONFIG" "$ZLIBFILES" ""
+		fi
+		if [ x"no" == x$EXTERNAL_LIBXML ]; then 
+			execConfigure "third_party" "libxml2-2.7.7" "$LIBXMLCONFIG" "$LIBXMLFILES" "$CONFIG_OPT"
+		fi
+		$PYTHON_PATH generate.py --include Makefile.xml --config-dir $BUILDDIR --with-zlib=$EXTERNAL_ZLIB --with-zlib-cppflags="$EXTERNAL_ZLIB_CPPFLAGS" --with-zlib-ldflags="$EXTERNAL_ZLIB_LDFLAGS" --with-libxml=$EXTERNAL_LIBXML --with-libxml-cppflags="$EXTERNAL_LIBXML_CPPFLAGS" --with-libxml-ldflags="$EXTERNAL_LIBXML_LDFLAGS" $PLATFORM
+		if [ $? -ne 0 ]; then
+			echo "*** error generating Makefile!"
+			exit 1
+		fi
+	else
+		echo "Need python version >2.6.1. You have \"$PYTHON_VERSION\"."
+	fi
+else
+	echo "Can not guess PLATFORM quadruple. It is set to \"$PLATFORM\" but it should be something like \"linux-debug-gcc-i386\"."
+fi
+echo "Configured platform $PLATFORM."
+echo "Executables will be generated in \"build/$PLATFORM\"."
+

+ 1 - 0
debian/..svnbridge/rules

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 6 - 0
debian/README

@@ -0,0 +1,6 @@
+The Debian Package libopc
+----------------------------
+
+Comments regarding the Package
+
+ -- Florian Reuter <flr@acm.org>  Tue, 31 May 2011 11:53:02 -0700

+ 5 - 0
debian/changelog

@@ -0,0 +1,5 @@
+libopc (0.0.2) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Florian Reuter <flr@acm.org>  Tue, 31 May 2011 11:53:02 -0700

+ 1 - 0
debian/compat

@@ -0,0 +1 @@
+7

+ 31 - 0
debian/control

@@ -0,0 +1,31 @@
+Source: libopc
+Priority: optional
+Maintainer: Florian Reuter <flr@acm.org>
+Build-Depends: debhelper (>= 7.0.50~), python (>= 2.6.1~)
+Standards-Version: 3.9.1
+Section: libs
+Homepage: http://libopc.codeplex.com
+#Vcs-Git: git://git.debian.org/collab-maint/libopc.git
+#Vcs-Browser: http://git.debian.org/?p=collab-maint/libopc.git;a=summary
+
+Package: libopc-dev
+Section: libdevel
+Architecture: any
+Depends: libopc (= ${binary:Version}), libxml2-dev, zlib1g-dev, ${misc:Depends}
+Description: Headers and static libraries for libopc
+ This package is needed to develop application which use libopc. It contains
+ all headers as well as static versions of the libopc libraries.
+
+Package: libopc
+#Section: libs # removed since lintian complained.
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Library for handling ISO/IEC 29500 container
+ The Open Packaging Convention (OPC) is part of the ISO/IEC 29500 specification 
+ which standardizes word-processing, spreadsheet and presentation documents. A 
+ prominent implementer of the new standard is Microsoft Office Version 2007 and
+ beyond. Every .docx, .xslx, .pptx document is an OPC container. Libopc has 
+ functions to read/write OPC container.
+ Another part of ISO/IEC 29500 is Markup Compatibility and Extensibility (MCE).
+ Libopc also has features to parse and generate XML markup compatible with MCE.
+

+ 33 - 0
debian/copyright

@@ -0,0 +1,33 @@
+Format: http://dep.debian.net/deps/dep5
+Upstream-Name: libopc
+Source: libopc.codeplex.com
+
+Files: *
+Copyright: 2011 Florian Reuter <flr@acm.org>
+License: BSD-3-Clause
+
+License: BSD-3-Clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+

+ 2 - 0
debian/libopc-dev.dirs

@@ -0,0 +1,2 @@
+usr/lib
+usr/include

+ 6 - 0
debian/libopc-dev.install

@@ -0,0 +1,6 @@
+usr/include/*
+usr/lib/libopc.a
+usr/lib/libmce.a
+usr/lib/libplib.a
+usr/lib/pkgconfig/libopc.pc
+

+ 2 - 0
debian/libopc.install

@@ -0,0 +1,2 @@
+usr/lib/*.so
+

+ 15 - 0
debian/rules

@@ -0,0 +1,15 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+export DH_VERBOSE=1
+override_dh_auto_configure:
+	./configure --with-zlib=yes --with-zlib-ldflags="`pkg-config zlib --libs`" --with-libxml=yes --with-libxml-cppflags="`pkg-config libxml-2.0 --cflags`" --with-libxml-ldflags="`pkg-config libxml-2.0 --libs`" --arch=any --target=release
+
+%:
+	dh $@ 

+ 1 - 0
debian/source/format

@@ -0,0 +1 @@
+3.0 (native)

+ 9 - 0
debian/source/options

@@ -0,0 +1,9 @@
+extend-diff-ignore = "*third_party*|*svn*|*git*|*test_docs*|*\.pyc|*buid*|Makefile"
+tar-ignore = third_party
+tar-ignore = test_docs
+tar-ignore = .svn
+tar-ignore = .git
+tar-ignore = *.pyc
+tar-ignore = build
+tar-ignore = Makefile
+

+ 1124 - 0
generate.py

@@ -0,0 +1,1124 @@
+#!/usr/bin/python
+
+import sys
+import os
+import copy
+import xml.etree.ElementTree as etree
+import uuid
+import getopt
+import zipfile
+import shutil
+
+EXT_MAPPING = { ".c": "c", ".cc": "cpp", ".cpp": "cpp", ".h": "h", ".s": "s"}
+
+def parseError(str):
+    print("*** error: \""+str+"\"\n");
+
+def platformCompare(a, b):
+    return cmp(a.count('*'), b.count('*'))
+
+
+def platformSubseteqTest(a, b):
+    a4=a.split("-")
+    b4=b.split("-")
+    ret=len(a4)==len(b4)
+    i=0
+    while i<len(a4) and i<len(b4):        
+        ret=ret and (a4[i]==b4[i] or b4[i]=="*")
+        i=i+1
+#    sys.stderr.write("platformSubseteqTest("+a+", "+b+")="+str(ret))
+    return ret
+
+def parseFile(node, ctx, list):
+    path=node.attrib["path"]
+    abs_path=os.path.join(ctx["base"], ctx["root"], path)
+#    sys.stderr.write "path="+abs_path
+    filterMatch=True
+    if "platform" in node.attrib:
+        filter=node.attrib["platform"]
+        filterMatch=platformSubseteqTest(ctx["platform"], filter)
+        
+    if filterMatch:
+        file_ext=os.path.splitext(path)[1]
+        if file_ext in EXT_MAPPING:
+            ext=EXT_MAPPING[file_ext]
+            if os.path.exists(abs_path):
+                install=None
+                if "install" in node.attrib and node.attrib["install"]=="yes":
+                    install=os.path.dirname(os.path.relpath(abs_path, ctx["root"]))
+##                    sys.stderr.write install
+                file_item={ "path": abs_path, "ext": ext, "install": install }
+                if "x" in node.attrib:
+                    file_item["x"]=node.attrib["x"]
+                list.append(file_item)
+            else:
+                parseError("file "+abs_path+" does not exist!")
+        else:
+            parseError("extension "+file_ext+" is unknown")
+
+def parseFiles(target, node, ctx):
+    for child in list(node):
+        if child.tag=="file":
+            parseFile(child, ctx, target)
+        else:
+            parseError("unhandled element: "+child.tag)
+
+def setAttr(dict, node, tag):
+    if tag in node.attrib:
+        dict[tag]=node.attrib[tag]        
+
+def fallbackCompare(a, b):
+    return -cmp(a.count('-'), b.count('-'))
+
+
+def generateFallbackList(platform):
+    ret=[]
+    p4=platform.split("-")
+    for i in range(1<<len(p4)):
+        p=""
+        for j in range(len(p4)):
+            m=(i&(1<<j))==(1<<j)
+#            print " "+str(i)+" "+str(j)+" "+str(m)+" "+p
+            if m:
+                if len(p)>0:
+                    p=p+"-"
+                p=p+p4[j]
+        if len(p)>0:
+            ret.append(p)
+    ret.sort(fallbackCompare)
+    return ret
+
+def updateCtx(conf, ctx, node):
+    if "root" in node.attrib:
+        root=ctx["root"]
+        ctx=copy.copy(ctx)    
+        rel_prj_path=os.path.split(ctx["root"])[1]
+        prjconfigdir=os.path.join(ctx["config"], rel_prj_path, "config")
+#        print "rel_prj_path="+rel_prj_path+" prjconfigdir="+prjconfigdir
+        v=node.attrib["root"].format(platform=ctx["platform"], config=os.path.join(ctx["config"], "config"), prjconfig=prjconfigdir)
+        f=node.attrib["root"].format(platform="{platform}", config=os.path.join(ctx["config"], "config"), prjconfig=prjconfigdir)
+        if v!=f:
+            conf["format"][os.path.join(root, v)]=os.path.join(root, f)
+
+        ctx_root=os.path.join(root, v)
+        if not os.path.exists(ctx_root):
+            list=generateFallbackList(ctx["platform"])
+            for p in list:
+                v=node.attrib["root"].format(platform=p, config=os.path.join(ctx["config"], "config"), prjconfig=prjconfigdir)
+                if os.path.exists(os.path.join(root, v)):
+                    map=os.path.join(root, v)
+                    conf["mapping"][map]=ctx_root
+                    ctx_root=map
+                    list=[]
+        if not os.path.exists(ctx_root) and "platforms" in conf and ctx["platform"] in conf["platforms"] and "family" in conf["platforms"][ctx["platform"]]:
+            family=conf["platforms"][ctx["platform"]]["family"]
+            list=generateFallbackList(family)
+#            print "list="+str(list)
+            for p in list:
+                v=node.attrib["root"].format(platform=p, config=os.path.join(ctx["config"], "config"), prjconfig= prjconfigdir)
+                if os.path.exists(os.path.join(root, v)):
+                    map=os.path.join(root, v)
+                    conf["mapping"][map]=ctx_root
+                    ctx_root=map
+                    list=[]
+        ctx["root"]=ctx_root
+    return ctx
+
+def parseDefines(ctx, node, dict):
+    value=None
+    if "value" in node.attrib:
+        value=node.attrib["value"]
+    if "name" in node.attrib:
+        name=node.attrib["name"]
+        dict[name]=value    
+    else:
+               parseError("define syntax invalid ("+nv+")");
+
+def parseSettings(conf, node, ctx, lib):
+    if node.tag=="settings":
+        tag="defines"
+    elif node.tag=="export":
+        tag="exports"
+    else:
+               parseError("unknown setting: "+node.tag);
+    for child in list(node):
+        if child.tag=="define":
+            parseDefines(ctx, child, lib[tag])    
+                else:
+            parseError("unhanded element: "+child.tag)
+
+def parseDeps(node):    
+    if "dep" in node.attrib:
+        dep=node.attrib["dep"].split()
+        return dep
+    else:
+        return []
+
+
+
+def parseLibrary(conf, node, ctx, seq_type):
+    lib_name=node.attrib["name"]
+    lib_uuid=uuid.uuid5(uuid.NAMESPACE_URL, "urn:lib:"+lib_name)
+    lib={"name": lib_name, "uuid": lib_uuid, "source": { "files": []}, "header": { "files": [], "target": "", "includes": [] }, "defines": {}, "exports": {}, "deps": parseDeps(node), "mode": "c90", "align": "", "external": False }    
+    ctx=updateCtx(conf, ctx, node)
+    setAttr(lib, node, "mode")
+    setAttr(lib, node, "align")
+    if not(lib_name in ctx["externals"]) or not("external" in ctx["externals"][lib_name]) or not(ctx["externals"][lib_name]["external"]):
+        for child in list(node):
+            if child.tag=="source":
+                parseFiles(lib["source"]["files"], list(child), updateCtx(conf, ctx, child))
+            elif child.tag=="header":
+                setAttr(lib["header"], child, "target")
+                child_ctx=updateCtx(conf, ctx, child)
+                lib["header"]["includes"].append(child_ctx["root"])
+                parseFiles(lib["header"]["files"], list(child), child_ctx)
+            elif child.tag=="settings":
+                parseSettings(conf, child, ctx, lib)
+            elif child.tag=="export":
+                parseSettings(conf, child, ctx, lib)
+            else:
+                parseError("unhanded element: "+child.tag)
+    else:
+        sys.stderr.write("using external "+lib_name)
+        lib["external"]=True
+    conf[seq_type].append(lib)
+
+def isExcluded(conf, ctx, lib):
+#    sys.stderr.write conf["platforms"]
+    if ctx["platform"] in conf["platforms"]:
+        platform=conf["platforms"][ctx["platform"]]
+        return lib in platform["exclude"]
+    else:
+        return False
+
+def parsePlatform(conf, node, ctx):
+    if "name" in node.attrib:
+        name=node.attrib["name"]
+        platform={ "exclude": {}, "libs": [], "ldflags": "" }
+        setAttr(platform, node, "family")
+        setAttr(platform, node, "cc")
+        setAttr(platform, node, "ar")
+        setAttr(platform, node, "ld")
+        setAttr(platform, node, "cflags")
+        setAttr(platform, node, "cflags_c")
+        setAttr(platform, node, "cflags_cpp")
+        setAttr(platform, node, "cppflags")
+        setAttr(platform, node, "ldflags")
+        setAttr(platform, node, "host")
+        if "exclude" in node.attrib:
+            for prj in node.attrib["exclude"].split(" "):
+                platform["exclude"][prj]=None
+#            sys.stderr.write platform["exclude"]
+        if "libs" in node.attrib:
+            platform["libs"].extend(node.attrib["libs"].split(" "))
+        conf["platforms"][name]=platform
+    else:
+        parseError("no name given for platform")
+        
+
+def parseTargets(conf, node, ctx):
+    for child in list(node):
+        if child.tag=="include":
+            path=os.path.abspath(os.path.join(ctx["root"], child.attrib["path"]))
+            new_ctx=copy.copy(ctx)        
+            new_ctx["root"]=os.path.dirname(path)
+            parseConfiguration(conf, path, new_ctx)
+        elif child.tag=="library":
+            parseLibrary(conf, child, ctx, "libraries")
+        elif child.tag=="tool":
+            parseLibrary(conf, child, ctx, "tools")
+        elif child.tag=="platform":
+            parsePlatform(conf, child, ctx)
+        else:
+            parseError("unhanded element: "+child.tag)
+
+def parseConfiguration(conf, filename, ctx):
+    sys.stderr.write("parsing "+filename+"\n")
+    tree=etree.parse(filename)
+    if tree is not None:
+        parseTargets(conf, tree.getroot(), ctx)
+    else:
+        parseError("failed to open file \""+filename+"\"")
+
+
+
+def depClosure2(conf, deps, ignoreExternal):
+    ret=[]    
+    gray=set(deps)
+    black=set()
+    while len(gray)>0:
+        for lib in conf["libraries"]:
+            if lib["name"] in gray:
+                gray.remove(lib["name"])
+                black.add(lib["name"])
+                if not(ignoreExternal) or not(lib["external"]):
+                    ret.append((lib, []))
+                    lib_deps=lib["deps"]
+                    for lib_dep in lib_deps:
+                        if not lib_dep in black:
+                            gray.add(lib_dep)
+    return ret
+
+def depCompare(a, b):
+    if a[0] in b[1]:
+        return 1
+    elif b[0] in a[1]:
+        return -1
+    else:
+        return 0
+
+def depClosureStr(req_deps, deps):
+    ret="depClosure("+str(req_deps)+") ="
+    for lib in deps:
+        ret=ret+" "+lib[0]["name"]+"<"
+        for x in lib[1]:
+            ret=ret+" "+x[0]["name"]
+        ret=ret+" >"
+    return ret
+
+def depClosure(conf, req_deps, ignoreExternal):
+    deps=depClosure2(conf, req_deps, ignoreExternal)
+    for lib in deps:
+        lib[1].extend(depClosure2(conf, lib[0]["deps"], ignoreExternal))
+#    print depClosureStr(req_deps, deps)
+#    deps.sort(depCompare)
+#    print depClosureStr(req_deps, deps)
+    ret=[]    
+    for lib in deps:
+        ret.append(lib[0]["name"])
+#    print "\n"
+    return ret
+
+def gatherIncludeDirs(conf, ctx, deps):
+    ret=[]
+    aux={}
+    for lib in conf["libraries"]:
+        if lib["name"] in deps:
+            for file in lib["header"]["files"]:
+                if file["install"] is not None:
+                    dir=os.path.dirname(file["path"])
+                    dir=os.path.abspath(dir.rstrip(file["install"]))
+                    dir=os.path.relpath(dir, ctx["base"])
+                    if dir not in aux:
+                        aux[dir]=None
+                        ret.append(dir)
+#    sys.stderr.write ret
+    return ret
+
+def gatherSources(conf, ctx, lib):
+    sources=[]
+    for file in lib["source"]["files"]:
+        rel_source=os.path.relpath(file["path"], ctx["base"])
+        sources.append((rel_source, file))
+    return sources
+
+#def generateOBJS(conf, ctx, lib, out, obj_dir, cppflags):
+#    objs=[]
+#    for file in lib["source"]["files"]:
+#        rel_source=os.path.relpath(file["path"], ctx["base"])
+#        rel_obj=os.path.join(obj_dir, os.path.splitext(rel_source)[0]+".o")
+#        out_dir=os.path.dirname(rel_obj)
+#        out.write(rel_obj+": "+rel_source+"\n")
+#        out.write("\t@mkdir -p "+out_dir+"\n")
+#        specific=""
+#        if file["ext"]=="c":
+#            specific ="$(CFLAGS_C) "
+#        elif file["ext"]=="cpp":
+#            specific ="$(CFLAGS_CPP) "
+#        out.write("\t$(CC) -c $(CFLAGS) "+ specific +"$(CPPFLAGS)"+cppflags+" "+ rel_source+" -o "+rel_obj+"\n")
+#        objs.append(rel_obj)
+#    return objs
+
+def generateDEPS(conf, ctx, lib, out, obj_dir, cppflags, filename):
+    for file in lib["source"]["files"]:
+        rel_source=os.path.relpath(file["path"], ctx["base"])
+        specific=""
+        if file["ext"]=="c":
+            specific ="$(CFLAGS_C) "
+        elif file["ext"]=="cpp":
+            specific ="$(CFLAGS_CPP) "
+        out.write("\tmakedepend -a -f"+filename+" $(CPPFLAGS)"+cppflags+" "+ rel_source+"\n")
+
+def generateCPPFLAGS(conf, ctx, lib, build_dir):
+    cppflags=""
+    for define in lib["defines"]:
+        if lib["defines"][define] is None:
+            cppflags=cppflags+" -D"+define
+        else:
+            cppflags=cppflags+" -D"+define+"="+lib["defines"][define]
+    for dir in lib["header"]["includes"]:
+        abs_dir=os.path.abspath(dir)
+        rel_dir=os.path.relpath(abs_dir, os.path.join(ctx["base"], build_dir))
+#        sys.stderr.write("abs_dir="+str(abs_dir)+" build_dir="+os.path.join(ctx["base"], build_dir)+" rel_dir="+str(rel_dir))
+        cppflags=cppflags+" -I"+rel_dir
+    dep_closure=depClosure(conf, lib["deps"], False)
+    dep_dirs=gatherIncludeDirs(conf, ctx, dep_closure)
+    for dir in dep_dirs:
+        abs_dir=os.path.abspath(dir)
+        rel_dir=os.path.relpath(abs_dir, os.path.join(ctx["base"], build_dir))
+#        sys.stderr.write("abs_dir="+str(abs_dir)+" build_dir="+os.path.join(ctx["base"], build_dir)+" rel_dir="+str(rel_dir))
+        cppflags=cppflags+" -I"+rel_dir
+    for dep_lib in conf["libraries"]:
+        if dep_lib["name"] in ctx["externals"]:
+            ext_lib=ctx["externals"][dep_lib["name"]]
+            if "external" in ext_lib and ext_lib["external"]:                        
+                if "cppflags" in ext_lib:
+                    cppflags=cppflags+" "+ext_lib["cppflags"]
+
+    return cppflags
+
+
+def generateVCXPROJ(conf, ctx, lib, type):
+    filename=os.path.abspath("win32\\"+lib["name"]+"\\"+lib["name"]+".vcxproj")
+    filepath=os.path.dirname(filename)
+    prj_uuid=lib["uuid"]
+    sys.stderr.write("generating "+filename+"\n")
+    try:
+        os.makedirs(os.path.dirname(filename))
+    except OSError:
+        pass
+
+    out=open(filename, "w")
+    out.write("<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n");
+        out.write("<ItemGroup Label=\"ProjectConfigurations\">\n");
+        out.write(" <ProjectConfiguration Include=\"Debug|Win32\">\n");
+        out.write("   <Configuration>Debug</Configuration>\n");
+        out.write("   <Platform>Win32</Platform>\n");
+        out.write(" </ProjectConfiguration>\n");
+        out.write("<ProjectConfiguration Include=\"Release|Win32\">\n");
+        out.write("   <Configuration>Release</Configuration>\n");
+        out.write("   <Platform>Win32</Platform>\n");
+        out.write("</ProjectConfiguration>\n");
+    out.write("</ItemGroup>\n");
+        out.write("<PropertyGroup Label=\"Globals\">\n");
+        out.write("    <ProjectGuid>{"+str(prj_uuid)+"}</ProjectGuid>\n");
+        out.write("    <Keyword>Win32Proj</Keyword>\n");
+        out.write("    <RootNamespace>"+lib["name"]+"</RootNamespace>\n");
+        out.write("</PropertyGroup>\n");
+        out.write("<Import Project=\"$(VCTargetsPath)\Microsoft.Cpp.default.props\" />\n");
+        out.write("  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n");
+        out.write("    <ConfigurationType>"+type+"</ConfigurationType>\n");
+        out.write("    <UseDebugLibraries>true</UseDebugLibraries>\n");
+        out.write("    <CharacterSet>Unicode</CharacterSet>\n");
+        out.write("  </PropertyGroup>\n");
+        out.write("  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n");
+        out.write("    <ConfigurationType>"+type+"</ConfigurationType>\n");
+        out.write("    <UseDebugLibraries>false</UseDebugLibraries>\n");
+        out.write("    <WholeProgramOptimization>true</WholeProgramOptimization>\n");
+        out.write("    <CharacterSet>Unicode</CharacterSet>\n");
+        out.write("  </PropertyGroup>\n");
+        out.write("<Import Project=\"$(VCTargetsPath)\Microsoft.Cpp.props\" />\n");
+        out.write("<ImportGroup Label=\"ExtensionSettings\" />\n");
+        out.write("<ImportGroup Label=\"PropertySheets\" />\n");
+        out.write("<PropertyGroup Label=\"UserMacros\" />\n");
+        out.write("<PropertyGroup />\n");
+        out.write("<ItemDefinitionGroup>\n");
+    out.write("<ClCompile>\n");
+    dep_closure=depClosure(conf, lib["deps"], False)
+    cpp_defs="WIN32;"
+    for define in lib["defines"]:
+        if lib["defines"][define] is None:
+            cpp_defs=cpp_defs+define+";"
+        else:
+            cpp_defs=cpp_defs+define+"="+lib["defines"][define]+";"
+    for dep in dep_closure:
+        for dep_lib in conf["libraries"]:
+            if dep_lib["name"]==dep and not isExcluded(conf, ctx, dep):
+                for define in dep_lib["exports"]:
+                    if dep_lib["exports"][define] is None:
+                        cpp_defs=cpp_defs+define+";"
+                    else:
+                        cpp_defs=cpp_defs+define+"="+dep_lib["defines"][define]+";"
+    cpp_defs=cpp_defs+"_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)"
+    out.write("<PreprocessorDefinitions>"+cpp_defs+"</PreprocessorDefinitions>\n" )
+    AdditionalIncludeDirectories=""
+    for dir in lib["header"]["includes"]:
+        AdditionalIncludeDirectories=AdditionalIncludeDirectories+os.path.relpath(os.path.abspath(dir), filepath)+";"    
+    dep_dirs=gatherIncludeDirs(conf, ctx, dep_closure)
+    for dir in dep_dirs:
+        abs_path=os.path.relpath(os.path.abspath(dir), filepath)
+        AdditionalIncludeDirectories=AdditionalIncludeDirectories+abs_path+";"
+    AdditionalIncludeDirectories=AdditionalIncludeDirectories+"%(AdditionalIncludeDirectories)"
+    out.write("<AdditionalIncludeDirectories>"+AdditionalIncludeDirectories+"</AdditionalIncludeDirectories>\n")
+    if "c99"==lib["mode"]:
+        out.write("<CompileAs>CompileAsCpp</CompileAs>\n");
+    if ""!=lib["align"]:
+        out.write("<StructMemberAlignment>"+lib["align"]+"Byte</StructMemberAlignment>\n");
+    out.write("</ClCompile>\n");
+    if "Application"==type:
+        out.write("<Link>\n");
+        out.write("<AdditionalDependencies>")
+        if ctx["platform"] in conf["platforms"]:
+            ext_libs=conf["platforms"][ctx["platform"]]["libs"]
+        else:
+            ext_libs={}
+#        sys.stderr.write ext_libs
+        for ext_lib in ext_libs:
+#            sys.stderr.write ext_lib
+            out.write(ext_lib+";")
+        out.write("%(AdditionalDependencies)</AdditionalDependencies> \n")
+        out.write("</Link>\n");
+        out.write("</ItemDefinitionGroup>\n");
+
+
+    out.write("<ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n")
+    out.write("<ClCompile>\n");
+    out.write("<WarningLevel>Level3</WarningLevel>\n")
+    out.write("<Optimization>Disabled</Optimization>\n")
+    out.write("<DisableSpecificWarnings>4996</DisableSpecificWarnings>\n")
+    out.write("</ClCompile>\n");
+    if "Application"==type:
+        out.write("<Link>\n");
+        out.write("<GenerateDebugInformation>true</GenerateDebugInformation>\n")
+        out.write("<SubSystem>Console</SubSystem>\n")
+        out.write("</Link>\n");    
+        out.write("</ItemDefinitionGroup>\n");
+
+    out.write("<ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n")
+    out.write("<ClCompile>\n")
+    out.write("<Optimization>MaxSpeed</Optimization>\n")
+    out.write("<DisableSpecificWarnings>4996</DisableSpecificWarnings>\n")
+    out.write("<FunctionLevelLinking>true</FunctionLevelLinking> \n")
+    out.write("<IntrinsicFunctions>true</IntrinsicFunctions> \n")
+    out.write("</ClCompile>\n");
+    if "Application"==type:
+        out.write("<Link>\n");
+        out.write("<GenerateDebugInformation>false</GenerateDebugInformation>\n")
+        out.write("<SubSystem>Console</SubSystem>\n")
+        out.write("<EnableCOMDATFolding>true</EnableCOMDATFolding>\n")
+        out.write("<OptimizeReferences>true</OptimizeReferences>\n")
+        out.write("</Link>\n");    
+        out.write("</ItemDefinitionGroup>\n");
+
+    out.write("<ItemGroup>\n");
+        for file in lib["header"]["files"]:
+        if "h"==file["ext"]:
+            out.write("  <ClInclude Include=\""+os.path.relpath(file["path"], filepath)+"\"/>\n");
+        out.write("</ItemGroup>\n");
+        out.write("<ItemGroup>\n");
+        for file in lib["source"]["files"]:
+        if "cpp"==file["ext"] or "c"==file["ext"] or "s"==file["ext"]:
+            out.write("  <ClCompile Include=\""+os.path.relpath(file["path"], filepath)+"\">\n");
+            out.write("  </ClCompile>\n");
+        out.write("</ItemGroup>\n");
+        out.write("<ItemGroup>\n");
+    for dep in dep_closure:
+        for dep_lib in conf["libraries"]:
+            if dep_lib["name"]==dep and not isExcluded(conf, ctx, dep_lib["name"]):
+                out.write("<ProjectReference Include=\"../"+dep_lib["name"]+"/"+dep_lib["name"]+".vcxproj\">\n")
+                out.write("<Project>{"+str(dep_lib["uuid"])+"}</Project>\n")
+                out.write("</ProjectReference>\n")
+        out.write("</ItemGroup>\n")
+        out.write("<Import Project=\"$(VCTargetsPath)\Microsoft.Cpp.targets\" />\n");
+        out.write("<ImportGroup Label=\"ExtensionTargets\" />\n");
+        out.write("</Project>\n");
+    out.close()
+
+def writeProject(out, solution_uuid, lib):
+    out.write("Project(\"{"+str(solution_uuid)+"}\") = \""+lib["name"]+"\", \""+lib["name"]+"\\"+lib["name"]+".vcxproj\", \"{"+str(lib["uuid"])+"}\"\n")
+    out.write("EndProject\n")
+
+def generatePlatformList(conf, ctx):
+    add=[]
+    for platform in conf["platforms"]:
+        if platformSubseteqTest(ctx["platform"], platform):
+            add.append(platform)
+    add.sort(platformCompare)
+    return add
+
+def generateConfiguration(ctx, includes, platform):
+    conf={ "libraries": [], "tools": [], "platforms": {}, "mapping": {}, "format": {} }
+    ctx["platform"]=platform
+    for include in includes:
+        parseConfiguration(conf, include, ctx)
+    if ctx["platform"] not in conf["platforms"]:    
+        add=generatePlatformList(conf, ctx);
+        if len(add)>0:
+            conf["platforms"][ctx["platform"]]=conf["platforms"][add[0]]
+    return conf
+
+def generateWin32(ctx, source):
+    platform=ctx["platforms"][0]
+    conf=generateConfiguration(ctx, [source], platform)
+#    sys.stderr.write conf
+        sys.stderr.write("generate win32 project")
+    for lib in conf["libraries"]:
+        if not isExcluded(conf, ctx, lib["name"]):
+            generateVCXPROJ(conf, ctx, lib, "StaticLibrary")
+    for tool in conf["tools"]:
+        if not isExcluded(conf, ctx, tool["name"]):
+            generateVCXPROJ(conf, ctx, tool, "Application")
+    solution_file=os.path.abspath("win32\\solution.sln")
+    solution_uuid=uuid.uuid5(uuid.NAMESPACE_URL, solution_file)
+    out=open(solution_file, "w")
+    out.write("\n")
+    out.write("Microsoft Visual Studio Solution File, Format Version 11.00\n")
+    for lib in conf["libraries"]:
+        if not isExcluded(conf, ctx, lib["name"]):
+            writeProject(out, solution_uuid, lib)
+    for tool in conf["tools"]:
+        if not isExcluded(conf, ctx, tool["name"]):
+            writeProject(out, solution_uuid, tool)
+    out.write("\n")
+    out.close()
+
+
+def writeSourceRules(conf, ctx, lib_type, out, lib, build_dir):
+    dirs={}
+    sources=gatherSources(conf, ctx, lib)
+    out.write("objs_"+lib["name"]+"=\\\n")
+    for source in sources:
+        out.write("     $(BUILD_DIR)/"+os.path.splitext(source[0])[0]+".o\\\n")
+        dirs[os.path.dirname(source[0])]=None
+    out.write("     \n")
+    out.write(lib["name"]+"_includes="+generateCPPFLAGS(conf, ctx, lib, build_dir)+"\n")
+    out.write("\n")
+    includes="$("+lib["name"]+"_includes)"
+    lib_type_flags=""
+    if lib_type=="shared":
+        if platformSubseteqTest(ctx["platform"], "linux-*-gcc-*"):
+            lib_type_flags=" -fPIC -DPIC"
+        elif platformSubseteqTest(ctx["platform"], "darwin-*-gcc-*"):
+            lib_type_flags=" -fno-common"
+    # write special rules
+    for source in sources:
+        file=source[1]
+        if "x" in file:
+            special="-x "+file["x"]+" "
+            out.write("$(BUILD_DIR)/"+os.path.splitext(source[0])[0]+".o: $(SRC_DIR)/"+source[0]+"\n")
+            out.write("\t@mkdir -p $(dir $@)\n")
+            out.write("\t$(CC) $(CFLAGS) $(CFLAGS_C) $(CPPFLAGS) "+special+includes+lib_type_flags+" -c \"$<\" -o \"$@\"\n")
+    # write generic rules
+    for dir in dirs:
+        for ext in EXT_MAPPING:
+            if EXT_MAPPING[ext]=='c' or EXT_MAPPING[ext]=='s':
+                out.write("$(BUILD_DIR)/"+dir+"/%.o: $(SRC_DIR)/"+dir+"/%"+ext+"\n")
+                out.write("\t@mkdir -p $(dir $@)\n")
+                out.write("\t$(CC) $(CFLAGS) $(CFLAGS_C) $(CPPFLAGS) "+includes+lib_type_flags+" -c \"$<\" -o \"$@\"\n")
+                out.write("\n")
+            elif EXT_MAPPING[ext]=='cpp':
+                out.write("$(BUILD_DIR)/"+dir+"/%.o: $(SRC_DIR)/"+dir+"/%"+ext+"\n")
+                out.write("\t@mkdir -p $(dir $@)\n")
+                out.write("\t$(CC) $(CFLAGS) $(CFLAGS_CPP) $(CPPFLAGS) "+includes+lib_type_flags+" -c \"$<\" -o \"$@\"\n")
+                out.write("\n")
+
+def writeMakefileFlags(conf, ctx, out):
+    platform=ctx["platform"]
+    out.write("CC="+conf["platforms"][platform]["cc"]+"\n");
+    out.write("AR="+conf["platforms"][platform]["ar"]+"\n");
+    out.write("CFLAGS="+conf["platforms"][platform]["cflags"]+"\n")
+    out.write("CFLAGS_C="+conf["platforms"][platform]["cflags_c"]+"\n")
+    out.write("CFLAGS_CPP="+conf["platforms"][platform]["cflags_cpp"]+"\n")
+    out.write("CPPFLAGS="+conf["platforms"][platform]["cppflags"]+"\n");
+    out.write("LDFLAGS="+conf["platforms"][platform]["ldflags"]+"\n");
+
+def getSharedExt(conf, ctx):
+    if platformSubseteqTest(ctx["platform"], "darwin-*-gcc-*"):
+        return ".dylib"
+    else:
+        return ".so"
+
+def generateExtLDFlags(conf, ctx):
+    ext_ldflags=""
+    for dep_lib in conf["libraries"]:
+        if dep_lib["name"] in ctx["externals"]:
+            ext_lib=ctx["externals"][dep_lib["name"]]
+            if "external" in ext_lib and ext_lib["external"]:                        
+                if "ldflags" in ext_lib:
+                    ext_ldflags=ext_ldflags+" "+ext_lib["ldflags"]
+    return ext_ldflags
+
+def generateLDFlags(conf, ctx, lib_type, initial_deps, exclude_deps, lib_form):
+    ret=""
+    deps=depClosure(conf, initial_deps, True)
+    for dep in deps:
+        if not(dep in exclude_deps):
+            if lib_type=="static":
+                ret=ret+" $(BUILD_DIR)/lib"+dep+".a"
+            if lib_type=="shared":
+                if lib_form:
+                    ret=ret+" -L$(BUILD_DIR) -l"+dep
+                else:
+                    ret=ret+" $(BUILD_DIR)/lib"+dep+getSharedExt(conf, ctx)
+
+    return ret
+
+
+def generateLibraryMakefile(conf, ctx, lib_type, lib, filename, build_dir, src_dir):
+    sys.stderr.write("generating "+filename+"\n")
+    if not os.path.exists(os.path.dirname(filename)):
+            os.makedirs(os.path.dirname(filename))
+    out=open(filename, "w")
+    out.write("# Generated.\n")
+    # compiler flags
+    writeMakefileFlags(conf, ctx, out)
+    out.write("BUILD_DIR=.\n")
+    out.write("SRC_DIR="+src_dir+"\n")
+    out.write("\n")
+    out.write(".PHONY: all clean\n")
+    out.write("\n")
+    out.write("# library "+lib["name"]+"\n")
+    out.write("all:")
+    if lib_type=="static":
+        out.write(" $(BUILD_DIR)/lib"+lib["name"]+".a")
+    if lib_type=="shared":
+        out.write(" $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx))
+    out.write("\n\n")
+    writeSourceRules(conf, ctx, lib_type, out, lib, build_dir)
+    if lib_type=="static":
+        out.write("$(BUILD_DIR)/lib"+lib["name"]+".a: $(objs_"+lib["name"]+")\n")
+        out.write("\t$(AR) -rcs $(BUILD_DIR)/lib"+lib["name"]+".a $(objs_"+lib["name"]+")\n")
+        out.write("\n")
+    if lib_type=="shared":
+        ld_deps=generateLDFlags(conf, ctx, lib_type, lib["deps"], [lib["name"]], True)+generateExtLDFlags(conf, ctx)
+        out.write("$(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx)+": $(objs_"+lib["name"]+")\n")
+        if platformSubseteqTest(ctx["platform"], "darwin-*-gcc-*"):
+            out.write("\t$(CC) -dynamiclib -install_name lib"+lib["name"]+getSharedExt(conf, ctx)+" -o $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx)+" $(objs_"+lib["name"]+")"+ld_deps+"\n")
+        else:
+            out.write("\t$(CC) -shared -Wl,-soname,lib"+lib["name"]+getSharedExt(conf, ctx)+" -Wl,-z,defs  -fPIC -o $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx)+" $(objs_"+lib["name"]+")"+ld_deps+" -lc\n")
+            out.write("\tstrip --remove-section=.comment --remove-section=.note --strip-unneeded $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx))
+        out.write("\n")
+    out.write("clean:\n")
+    out.write("\trm -rf $(BUILD_DIR)/lib"+lib["name"]+".a $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx)+" $(objs_"+lib["name"]+")\n")
+    out.close()
+    
+def generateLibraryInclude(conf, ctx, lib, filename, build_dir, src_dir):
+    sys.stderr.write("generating "+filename+"\n")
+    if not os.path.exists(os.path.dirname(filename)):
+            os.makedirs(os.path.dirname(filename))
+    ret=[]
+    lib_deps=lib["deps"]
+    lib_deps.append(lib["name"])
+#    out.write("deps="+str(lib["deps"])+"\n");
+    dep_closure=depClosure(conf, lib_deps, False)
+    dep_dirs=gatherIncludeDirs(conf, ctx, dep_closure)
+    for dep in dep_dirs:
+        dep_dir=os.path.join(ctx["base"], str(dep))
+        if dep_dir in conf["mapping"]:
+            dep_dir=conf["mapping"][dep_dir]
+        if dep_dir in conf["format"]:
+            ln_src=os.path.join(build_dir, "include", os.path.relpath(conf["format"][dep_dir], ctx["base"]).format(platform="platform").replace(os.sep, "_"))
+            ln_dst=os.path.join(src_dir, dep)
+            if os.path.exists(ln_src):
+                os.remove(ln_src)
+            print "symlink("+ln_dst+", "+ln_src+")"+str(os.path.exists(ln_src))
+            os.symlink(ln_dst, ln_src)
+            ret.append(ln_src)
+        else:
+            ret.append(dep)
+
+    out=open(filename, "w")
+    for file in ret:
+        out.write(file+"\n")
+    out.close()
+
+
+def generateToolMakefile(conf, ctx, lib_type, tool, filename, build_dir, src_dir):
+    sys.stderr.write("generating "+filename+"\n")
+    if not os.path.exists(os.path.dirname(filename)):
+            os.makedirs(os.path.dirname(filename))
+    out=open(filename, "w")
+    out.write("# Generated.\n")
+    # compiler flags
+    writeMakefileFlags(conf, ctx, out)
+    out.write("BUILD_DIR=.\n")
+    out.write("SRC_DIR="+src_dir+"\n")
+    out.write("\n")
+    out.write(".PHONY: all clean\n")
+    out.write("\n")
+    out.write("# tool "+tool["name"]+"\n")
+    out.write("all: $(BUILD_DIR)/"+ tool["name"]+"\n\n")
+    writeSourceRules(conf, ctx, "static", out, tool, build_dir)
+    out.write(tool["name"]+"_ld="+generateLDFlags(conf, ctx, lib_type, tool["deps"], [], False)+"\n")
+#    deps=depClosure(conf, tool["deps"], True)
+#    for dep in deps:
+#        if lib_type=="static":
+#            out.write(" $(BUILD_DIR)/lib"+ dep +".a")    
+#        if lib_type=="shared":
+#            out.write(" $(BUILD_DIR)/lib"+ dep +getSharedExt(conf, ctx))    
+#    out.write("\n")
+    ext_ldflags=generateExtLDFlags(conf, ctx)
+#    ext_ldflags=""
+#    for dep_lib in conf["libraries"]:
+#        if dep_lib["name"] in ctx["externals"]:
+#            ext_lib=ctx["externals"][dep_lib["name"]]
+#            if "external" in ext_lib and ext_lib["external"]:                        
+#                if "ldflags" in ext_lib:
+#                    ext_ldflags=ext_ldflags+" "+ext_lib["ldflags"]
+
+    out.write("$(BUILD_DIR)/"+tool["name"]+": $(objs_"+tool["name"]+") $("+tool["name"]+"_ld)\n")            
+    static_flag=""
+    if lib_type=="static" and platformSubseteqTest(ctx["platform"], "linux-*-gcc-*"):
+        static_flag=" --static"
+    out.write("\t$(CC) $(CFLAGS) $(CPPFLAGS) -o $(BUILD_DIR)/"+tool["name"]+" $(objs_"+tool["name"]+") "+generateLDFlags(conf, ctx, lib_type, tool["deps"], [], True)+ ext_ldflags+" $(LDFLAGS)\n")
+    out.write("\n")
+    out.write("clean:\n")
+    out.write("\trm -f $(BUILD_DIR)/"+tool["name"]+" $(objs_"+tool["name"]+")\n")
+
+
+def generateTypedMakefile(conf, ctx, lib_type):
+    obj_dir=os.path.join("build", ctx["platform"], lib_type)
+    filename=os.path.join(obj_dir, "Makefile")
+    sys.stderr.write("generating "+filename+"\n")
+    if not os.path.exists(os.path.dirname(filename)):
+            os.makedirs(os.path.dirname(filename))
+    out=open(filename, "w")
+    out.write("# Generated.\n")
+
+    # generate phony targets
+    out.write(".PHONY: all clean tools dep")
+    for lib in conf["libraries"]:
+        if not lib["external"]:
+            out.write(" "+lib["name"])
+    for tool in conf["tools"]:
+        out.write(" "+tool["name"])
+    out.write("\n")
+    # all
+    out.write("all:")
+    for lib in conf["libraries"]:
+        if not lib["external"]:
+            out.write(" "+lib["name"])
+    out.write(" tools\n")
+    # tools
+    out.write("tools:")
+    for tool in conf["tools"]:
+        out.write(" "+tool["name"])
+    out.write("\n")
+
+    # generate libs
+    for lib in conf["libraries"]:
+        if not lib["external"]:
+            makefile=os.path.join(obj_dir, "Makefile."+lib["name"])
+            generateLibraryMakefile(conf, ctx, lib_type, lib, makefile, obj_dir, os.path.join("..", "..", ".."))
+            libincludefile=os.path.join(obj_dir, "include", lib["name"]+".inc")
+            generateLibraryInclude(conf, ctx, lib, libincludefile, obj_dir, os.path.join("..", "..", "..", ".."))
+            out.write(lib["name"]+":")
+            deps=depClosure(conf, lib["deps"], True)
+            for dep in deps:
+                if lib["name"]!=dep:
+                    out.write(" "+dep)
+            out.write("\n")
+            out.write("\t$(MAKE) -f "+"Makefile."+lib["name"]+"\n\n")
+    
+    # generate tools
+    for tool in conf["tools"]:
+        makefile=os.path.join(obj_dir, "Makefile."+tool["name"])
+        generateToolMakefile(conf, ctx, lib_type, tool, makefile, obj_dir, os.path.join("..", "..", ".."))
+        deps=depClosure(conf, tool["deps"], True)
+        out.write(tool["name"]+":")
+        for dep in deps:
+            if tool["name"]!=dep:
+                out.write(" "+dep)
+        out.write("\n")
+        out.write("\t$(MAKE) -f "+"Makefile."+ tool["name"]+"\n\n")
+
+    out.write("clean:\n")
+    for lib in conf["libraries"]:
+        if not lib["external"]:
+            out.write("\t$(MAKE) -f "+"Makefile."+lib["name"]+" clean\n")
+    for tool in conf["tools"]:
+        out.write("\t$(MAKE) -f "+"Makefile."+tool["name"]+" clean\n")
+
+
+#    out.write("dep:\n")
+#    for lib in conf["libraries"]:
+#        generateDEPS(conf, ctx, lib, out, obj_dir, generateCPPFLAGS(conf, ctx, lib), filename)
+#    for tool in conf["tools"]:
+#        generateDEPS(conf, ctx, tool, out, obj_dir, generateCPPFLAGS(conf, ctx, tool), filename)
+
+    out.write("package: all\n")
+    out.write("\tcd ../../.. && ./generate.py --include Makefile.xml");
+    for ext_lib in ctx["externals"]:
+        if ctx["externals"][ext_lib]["external"]:
+            name=ext_lib
+            if "xml"==ext_lib:
+                name="libxml"
+            out.write(" --with-"+name+"=yes")
+            if "cppflags" in ctx["externals"][ext_lib]:
+                out.write(" --with-"+name+"-cppflags=\""+ctx["externals"][ext_lib]["cppflags"]+"\"")
+            if "ldflags" in ctx["externals"][ext_lib]:
+                out.write(" --with-"+name+"-ldflags=\""+ctx["externals"][ext_lib]["ldflags"]+"\"")
+    out.write(" --package package_"+lib_type+".zip --type "+lib_type)
+    out.write(" --config-dir "+ctx["config"]+" "+ctx["platform"])
+    out.write("\n")
+
+    obj_dir=os.path.join(ctx["base"], "build", ctx["platform"], lib_type)
+    tool_ext=""
+    if lib_type=="static":
+        lib_ext=".a"
+    else:
+        lib_ext=getSharedExt(conf, ctx)
+    lib_prefix="lib"
+    base="$(DESTDIR)/usr/"
+    out.write("install: all\n")
+    for lib in conf["libraries"]:
+        if not lib["external"] and not isExcluded(conf, ctx, lib["name"]):
+            for include in lib["header"]["files"]:
+                if None!=include["install"]:
+                    target=base+"include/"
+                    if len(include["install"])>0:
+                        target=target+include["install"]+"/"
+                    target=target+os.path.split(include["path"])[1]
+                    out.write("\t@mkdir -p "+os.path.dirname(target)+"\n")
+                    out.write("\t@cp "+include["path"]+" "+target+"\n")
+            target=base+"lib/"+lib_prefix+lib["name"]+lib_ext
+            out.write("\t@mkdir -p "+os.path.dirname(target)+"\n")
+            if lib_type=="shared":
+                out.write("\t@cp "+os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext)+" "+target+".1\n")
+                out.write("\tldconfig -v -n "+os.path.dirname(target)+"\n")
+            else:
+                out.write("\t@cp "+os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext)+" "+target+"\n")
+    for tool in conf["tools"]:
+        if not isExcluded(conf, ctx, tool["name"]):
+            target=base+"bin/"+tool["name"]+tool_ext
+            out.write("\t@mkdir -p "+os.path.dirname(target)+"\n")
+            out.write("\t@cp "+os.path.join(obj_dir, tool["name"]+tool_ext)+" "+target+"\n")
+    target=base+"lib/pkgconfig/libopc.pc"
+    out.write("\t@mkdir -p "+os.path.dirname(target)+"\n")    
+    out.write("\t@cp "+os.path.join(ctx["base"], "config", "libopc.pc")+" "+target+"\n")
+    out.close()
+
+
+def generateTypedMakefiles(ctx, source, lib_types):
+    for platform in ctx["platforms"]:
+        conf=generateConfiguration(ctx, [source], platform)
+        if ctx["platform"] in conf["platforms"]:    
+            for lib_type in lib_types:        
+                generateTypedMakefile(conf, ctx, lib_type)
+        else:
+            parseError("platform "+ctx["platform"]+" is unknown.")
+            sys.stderr.write("available platforms:");
+            for platform in conf["platforms"]:
+                sys.stderr.write(platform+"\n")
+    out=open("Makefile", "w")
+    out.write(".PHONY: all clean");
+    for platform in ctx["platforms"]:
+        for lib_type in lib_types:        
+            out.write(" "+platform+"."+lib_type);
+    for lib_type in lib_types:        
+        out.write(" "+lib_type);
+    out.write("\n");
+    out.write("all:");
+    for lib_type in lib_types:        
+        out.write(" "+lib_type);
+    out.write("\n");
+
+    for lib_type in lib_types:        
+        out.write(lib_type+":");
+        for platform in ctx["platforms"]:
+            out.write(" "+platform+"."+lib_type);
+        out.write("\n");
+
+    for lib_type in lib_types:        
+        for platform in ctx["platforms"]:
+            out.write(platform+"."+lib_type+": build"+os.sep+platform+os.sep+lib_type+os.sep+"Makefile\n");
+            out.write("\t@$(MAKE) -C build"+os.sep+platform+os.sep+lib_type+"\n");
+    out.write("clean:\n")
+    for lib_type in lib_types:        
+        for platform in ctx["platforms"]:
+            out.write("\t@$(MAKE) -C build"+os.sep+platform+os.sep+lib_type+" clean\n");    
+    out.write("package:\n")
+    for lib_type in lib_types:        
+        for platform in ctx["platforms"]:
+            out.write("\t@$(MAKE) -C build"+os.sep+platform+os.sep+lib_type+" package\n")
+    out.write("install:\n")
+    for lib_type in lib_types:        
+        for platform in ctx["platforms"]:
+            out.write("\t@$(MAKE) -C build"+os.sep+platform+os.sep+lib_type+" install\n")
+    out.close()
+
+def dumpEnvironment(ctx, includes, platform):
+    conf=generateConfiguration(ctx, includes, platform)
+    if platform in conf["platforms"]:            
+        p=conf["platforms"][platform]
+#        print(str(p))
+        host=""
+        if "host" in p:
+            host="HOST=\""+p["host"]+"\" "
+        sys.stdout.write("export CC=\""+p["cc"]+"\" "+
+             "export AR=\""+p["ar"]+"\" "+
+             "export LD=\""+p["ld"]+"\" "
+             "export CPPFLAGS=\""+p["cppflags"]+"\" "
+             "export CFLAGS=\""+p["cflags"]+"\" "+
+             host
+            )
+    else:
+        parseError("platform "+platform+" is unknown.")
+        sys.stderr.write("available platforms:");
+        for platform in conf["platforms"]:
+            sys.stderr.write(platform)    
+
+def set_external_flag(ctx, lib, flag, value):
+#    sys.stderr.write("SETTING "+lib+" "+flag+" "+str(value)+"\n")
+    if lib in ctx["externals"]:
+        ctx["externals"][lib][flag]=value
+    else:
+        ctx["externals"][lib]={flag: value}
+
+def is_external(ctx, lib):
+    if lib in ctx["externals"]:
+        if "external" in ctx["externals"][lib]:
+            return ctx["externals"][lib]["external"]
+        else:
+            return False
+    else:
+        return False
+
+
+def generateZipPackage(ctx, source, lib_type, install_zip):
+    zip=zipfile.ZipFile(install_zip, 'w', zipfile.ZIP_DEFLATED)
+    base=os.path.splitext(install_zip)[0]+"/"
+    platform=ctx["platforms"][0]
+    conf=generateConfiguration(ctx, [source], platform)
+    if platformSubseteqTest(ctx["platforms"][0], "win32-*-*"):
+        obj_dir=os.path.join("win32", ctx["platform"].split('-')[1])
+        tool_ext=".exe"
+        lib_exts=[".lib"]
+        if (lib_type=="shared"):
+            shared_exts.append(".dll")        
+        lib_prefix=""
+    else:
+        obj_dir=os.path.join("build", ctx["platform"], lib_type)
+        tool_ext=""
+        if lib_type=="shared":
+            lib_exts=[".dylib"]
+        else:
+            lib_exts=[".a"]
+        lib_prefix="lib"
+    for lib in conf["libraries"]:
+        if not lib["external"] and not isExcluded(conf, ctx, lib["name"]):
+            for include in lib["header"]["files"]:
+                if None!=include["install"]:
+                    target=base+"include/"
+                    if len(include["install"])>0:
+                        target=target+include["install"]+"/"
+                    target=target+os.path.split(include["path"])[1]
+                    zip.write(include["path"], target)
+            for lib_ext in lib_exts:
+                target=base+"lib/"+lib_prefix+lib["name"]+lib_ext
+#                print "ADD "+os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext)
+                zip.write(os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext), target)
+    for tool in conf["tools"]:
+        if not isExcluded(conf, ctx, tool["name"]):
+            target=base+"bin/"+tool["name"]+tool_ext
+            zip.write(os.path.join(obj_dir, tool["name"]+tool_ext), target)
+    zip.write(os.path.join("third_party", "LICENSE"), base+"/LICENSE.THIRD_PARTY")
+    zip.write("LICENSE", base+"/LICENSE")
+    zip.close()
+
+
+
+def installFiles(ctx, source, lib_type, base):
+    copy_ctx=None
+    platform=ctx["platforms"][0]
+    conf=generateConfiguration(ctx, [source], platform)
+    if platformSubseteqTest(ctx["platforms"][0], "win32-*-*"):
+        obj_dir=os.path.join("win32", ctx["platform"].split('-')[1])
+        tool_ext=".exe"
+        lib_exts=[".lib"]
+        lib_prefix=""
+    else:
+        obj_dir=os.path.join("build", ctx["platform"], lib_type)
+        tool_ext=""
+        lib_exts=[".a", getSharedExt(conf, ctx)]
+        lib_prefix="lib"
+    for lib in conf["libraries"]:
+        if not lib["external"] and not isExcluded(conf, ctx, lib["name"]):
+            for include in lib["header"]["files"]:
+                if None!=include["install"]:
+                    target=base+"include/"
+                    if len(include["install"])>0:
+                        target=target+include["install"]+"/"
+                    target=target+os.path.split(include["path"])[1]
+                    copyFile(copy_ctx, include["path"], target)
+            for lib_ext in lib_exts:
+                target=base+"lib/"+lib_prefix+lib["name"]+lib_ext
+                copyFile(copy_ctx, os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext), target)
+    for tool in conf["tools"]:
+        if not isExcluded(conf, ctx, tool["name"]):
+            target=base+"bin/"+tool["name"]+tool_ext
+            copyFile(copy_ctx, os.path.join(obj_dir, tool["name"]+tool_ext), target)
+    copyFile(copy_ctx, os.path.join("third_party", "LICENSE"), base+"/LICENSE.THIRD_PARTY")
+    copyFile(copy_ctx, "LICENSE", base+"/LICENSE")
+
+def usage():
+    print("usage:")
+    print(" generate [--include \"Makefile.xml\"]")
+    print("          [--config-dir \"config/\"]")
+    print("          [--print-env \"linux-release-gcc\"]")
+    print("          [--package \"xyz.zip/\"]")
+
+if __name__ == "__main__":    
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "h", ["help", "include=", "config-dir=", "print-env=", 
+            "package=", "install=", 
+            "with-zlib-cppflags=", "with-zlib-ldflags=", "with-zlib=",
+            "with-libxml-cppflags=", "with-libxml-ldflags=", "with-libxml=",
+            "type="])
+    except getopt.GetoptError, err:
+        # print help information and exit:
+        print str(err) # will print something like "option -a not recognized"
+        usage()
+        sys.exit(2)
+    ctx={ "base": os.path.abspath(os.curdir), "root": os.path.abspath(os.curdir), "platform": "?-?-?", "platforms": [], "externals": {} }
+    ctx["config"]=ctx["base"]
+    includes=[]
+    dump_env=[]
+    install_zip=None
+    target_type="static"
+    for o, a in opts:
+        if o in ("-h", "--help"):
+            usage()
+            sys.exit(0)
+        elif o in ("--include"):
+            includes.append(a)
+        elif o in ("--config-dir"):
+            ctx["config"]=os.path.join(ctx["base"], a)
+        elif o in ("--print-env"):
+            args=[]
+            dump_env=[a]
+        elif o in ("--package"):
+            install_zip=a
+        elif o in ("--install"):
+            install_files=a
+        elif o in ("--with-zlib"):
+            set_external_flag(ctx, "zlib", "external", "yes"==a)
+        elif o in ("--with-zlib-cppflags"):
+            set_external_flag(ctx, "zlib", "cppflags", a)
+        elif o in ("--with-zlib-ldflags"):
+            set_external_flag(ctx, "zlib", "ldflags", a)
+        elif o in ("--with-libxml"):
+            set_external_flag(ctx, "xml", "external", "yes"==a)
+        elif o in ("--with-libxml-cppflags"):
+            set_external_flag(ctx, "xml", "cppflags", a)
+        elif o in ("--with-libxml-ldflags"):
+            set_external_flag(ctx, "xml", "ldflags", a)
+        elif o in ("--type"):
+            target_type=a
+
+    for platform in args:
+        ctx["platforms"].append(platform)
+
+    if 1==len(ctx["platforms"]) and None!=install_zip and 1==len(includes):
+        ctx["root"]=os.path.abspath(os.path.split(includes[0])[0])
+        generateZipPackage(ctx, includes[0], target_type, install_zip)
+    elif 1==len(ctx["platforms"]) and platformSubseteqTest(ctx["platforms"][0], "win32-*-msvc-*") and 1==len(includes):
+        ctx["root"]=os.path.abspath(os.path.split(includes[0])[0])
+        generateWin32(ctx, includes[0])
+    else:
+        if is_external(ctx, "zlib") and is_external(ctx, "xml"):
+            lib_types=["static", "shared"]
+        else:
+            lib_types=["static"]
+        if not os.path.exists("build"):
+            os.makedirs("build")
+        f=open(os.path.join("build", "configure.ctx"), "w")
+        f.write(str(ctx))
+        f.close()        
+        for include in includes:
+            ctx["root"]=os.path.abspath(os.path.split(include)[0])
+            generateTypedMakefiles(ctx, include, lib_types)
+
+    for platform in dump_env:
+        dumpEnvironment(ctx, includes, platform)
+

+ 1124 - 0
generate.py.bak

@@ -0,0 +1,1124 @@
+#!/usr/bin/python
+
+import sys
+import os
+import copy
+import xml.etree.ElementTree as etree
+import uuid
+import getopt
+import zipfile
+import shutil
+
+EXT_MAPPING = { ".c": "c", ".cc": "cpp", ".cpp": "cpp", ".h": "h", ".s": "s"}
+
+def parseError(str):
+	print("*** error: \""+str+"\"\n");
+
+def platformCompare(a, b):
+	return cmp(a.count('*'), b.count('*'))
+
+
+def platformSubseteqTest(a, b):
+	a4=a.split("-")
+	b4=b.split("-")
+	ret=len(a4)==len(b4)
+	i=0
+	while i<len(a4) and i<len(b4):		
+		ret=ret and (a4[i]==b4[i] or b4[i]=="*")
+		i=i+1
+#	sys.stderr.write("platformSubseteqTest("+a+", "+b+")="+str(ret))
+	return ret
+
+def parseFile(node, ctx, list):
+	path=node.attrib["path"]
+	abs_path=os.path.join(ctx["base"], ctx["root"], path)
+#	sys.stderr.write "path="+abs_path
+	filterMatch=True
+	if "platform" in node.attrib:
+		filter=node.attrib["platform"]
+		filterMatch=platformSubseteqTest(ctx["platform"], filter)
+		
+	if filterMatch:
+		file_ext=os.path.splitext(path)[1]
+		if file_ext in EXT_MAPPING:
+			ext=EXT_MAPPING[file_ext]
+			if os.path.exists(abs_path):
+				install=None
+				if "install" in node.attrib and node.attrib["install"]=="yes":
+					install=os.path.dirname(os.path.relpath(abs_path, ctx["root"]))
+##					sys.stderr.write install
+				file_item={ "path": abs_path, "ext": ext, "install": install }
+				if "x" in node.attrib:
+					file_item["x"]=node.attrib["x"]
+				list.append(file_item)
+			else:
+				parseError("file "+abs_path+" does not exist!")
+		else:
+			parseError("extension "+file_ext+" is unknown")
+
+def parseFiles(target, node, ctx):
+	for child in list(node):
+		if child.tag=="file":
+			parseFile(child, ctx, target)
+		else:
+			parseError("unhandled element: "+child.tag)
+
+def setAttr(dict, node, tag):
+	if tag in node.attrib:
+		dict[tag]=node.attrib[tag]		
+
+def fallbackCompare(a, b):
+	return -cmp(a.count('-'), b.count('-'))
+
+
+def generateFallbackList(platform):
+	ret=[]
+	p4=platform.split("-")
+	for i in range(1<<len(p4)):
+		p=""
+		for j in range(len(p4)):
+			m=(i&(1<<j))==(1<<j)
+#			print " "+str(i)+" "+str(j)+" "+str(m)+" "+p
+			if m:
+				if len(p)>0:
+					p=p+"-"
+				p=p+p4[j]
+		if len(p)>0:
+			ret.append(p)
+	ret.sort(fallbackCompare)
+	return ret
+
+def updateCtx(conf, ctx, node):
+	if "root" in node.attrib:
+		root=ctx["root"]
+		ctx=copy.copy(ctx)	
+		rel_prj_path=os.path.split(ctx["root"])[1]
+		prjconfigdir=os.path.join(ctx["config"], rel_prj_path, "config")
+#		print "rel_prj_path="+rel_prj_path+" prjconfigdir="+prjconfigdir
+		v=node.attrib["root"].format(platform=ctx["platform"], config=os.path.join(ctx["config"], "config"), prjconfig=prjconfigdir)
+		f=node.attrib["root"].format(platform="{platform}", config=os.path.join(ctx["config"], "config"), prjconfig=prjconfigdir)
+		if v!=f:
+			conf["format"][os.path.join(root, v)]=os.path.join(root, f)
+
+		ctx_root=os.path.join(root, v)
+		if not os.path.exists(ctx_root):
+			list=generateFallbackList(ctx["platform"])
+			for p in list:
+				v=node.attrib["root"].format(platform=p, config=os.path.join(ctx["config"], "config"), prjconfig=prjconfigdir)
+				if os.path.exists(os.path.join(root, v)):
+					map=os.path.join(root, v)
+					conf["mapping"][map]=ctx_root
+					ctx_root=map
+					list=[]
+		if not os.path.exists(ctx_root) and "platforms" in conf and ctx["platform"] in conf["platforms"] and "family" in conf["platforms"][ctx["platform"]]:
+			family=conf["platforms"][ctx["platform"]]["family"]
+			list=generateFallbackList(family)
+#			print "list="+str(list)
+			for p in list:
+				v=node.attrib["root"].format(platform=p, config=os.path.join(ctx["config"], "config"), prjconfig= prjconfigdir)
+				if os.path.exists(os.path.join(root, v)):
+					map=os.path.join(root, v)
+					conf["mapping"][map]=ctx_root
+					ctx_root=map
+					list=[]
+		ctx["root"]=ctx_root
+	return ctx
+
+def parseDefines(ctx, node, dict):
+	value=None
+	if "value" in node.attrib:
+		value=node.attrib["value"]
+	if "name" in node.attrib:
+		name=node.attrib["name"]
+		dict[name]=value	
+	else:
+       		parseError("define syntax invalid ("+nv+")");
+
+def parseSettings(conf, node, ctx, lib):
+	if node.tag=="settings":
+		tag="defines"
+	elif node.tag=="export":
+		tag="exports"
+	else:
+       		parseError("unknown setting: "+node.tag);
+	for child in list(node):
+		if child.tag=="define":
+			parseDefines(ctx, child, lib[tag])	
+                else:
+			parseError("unhanded element: "+child.tag)
+
+def parseDeps(node):	
+	if "dep" in node.attrib:
+		dep=node.attrib["dep"].split()
+		return dep
+	else:
+		return []
+
+
+
+def parseLibrary(conf, node, ctx, seq_type):
+	lib_name=node.attrib["name"]
+	lib_uuid=uuid.uuid5(uuid.NAMESPACE_URL, "urn:lib:"+lib_name)
+	lib={"name": lib_name, "uuid": lib_uuid, "source": { "files": []}, "header": { "files": [], "target": "", "includes": [] }, "defines": {}, "exports": {}, "deps": parseDeps(node), "mode": "c90", "align": "", "external": False }	
+	ctx=updateCtx(conf, ctx, node)
+	setAttr(lib, node, "mode")
+	setAttr(lib, node, "align")
+	if not(lib_name in ctx["externals"]) or not("external" in ctx["externals"][lib_name]) or not(ctx["externals"][lib_name]["external"]):
+		for child in list(node):
+			if child.tag=="source":
+				parseFiles(lib["source"]["files"], list(child), updateCtx(conf, ctx, child))
+			elif child.tag=="header":
+				setAttr(lib["header"], child, "target")
+				child_ctx=updateCtx(conf, ctx, child)
+				lib["header"]["includes"].append(child_ctx["root"])
+				parseFiles(lib["header"]["files"], list(child), child_ctx)
+			elif child.tag=="settings":
+				parseSettings(conf, child, ctx, lib)
+			elif child.tag=="export":
+				parseSettings(conf, child, ctx, lib)
+			else:
+				parseError("unhanded element: "+child.tag)
+	else:
+		sys.stderr.write("using external "+lib_name)
+		lib["external"]=True
+	conf[seq_type].append(lib)
+
+def isExcluded(conf, ctx, lib):
+#	sys.stderr.write conf["platforms"]
+	if ctx["platform"] in conf["platforms"]:
+		platform=conf["platforms"][ctx["platform"]]
+		return lib in platform["exclude"]
+	else:
+		return False
+
+def parsePlatform(conf, node, ctx):
+	if "name" in node.attrib:
+		name=node.attrib["name"]
+		platform={ "exclude": {}, "libs": [], "ldflags": "" }
+		setAttr(platform, node, "family")
+		setAttr(platform, node, "cc")
+		setAttr(platform, node, "ar")
+		setAttr(platform, node, "ld")
+		setAttr(platform, node, "cflags")
+		setAttr(platform, node, "cflags_c")
+		setAttr(platform, node, "cflags_cpp")
+		setAttr(platform, node, "cppflags")
+		setAttr(platform, node, "ldflags")
+		setAttr(platform, node, "host")
+		if "exclude" in node.attrib:
+			for prj in node.attrib["exclude"].split(" "):
+				platform["exclude"][prj]=None
+#			sys.stderr.write platform["exclude"]
+		if "libs" in node.attrib:
+			platform["libs"].extend(node.attrib["libs"].split(" "))
+		conf["platforms"][name]=platform
+	else:
+		parseError("no name given for platform")
+		
+
+def parseTargets(conf, node, ctx):
+	for child in list(node):
+		if child.tag=="include":
+			path=os.path.abspath(os.path.join(ctx["root"], child.attrib["path"]))
+			new_ctx=copy.copy(ctx)		
+			new_ctx["root"]=os.path.dirname(path)
+			parseConfiguration(conf, path, new_ctx)
+		elif child.tag=="library":
+			parseLibrary(conf, child, ctx, "libraries")
+		elif child.tag=="tool":
+			parseLibrary(conf, child, ctx, "tools")
+		elif child.tag=="platform":
+			parsePlatform(conf, child, ctx)
+		else:
+			parseError("unhanded element: "+child.tag)
+
+def parseConfiguration(conf, filename, ctx):
+	sys.stderr.write("parsing "+filename+"\n")
+	tree=etree.parse(filename)
+	if tree is not None:
+		parseTargets(conf, tree.getroot(), ctx)
+	else:
+		parseError("failed to open file \""+filename+"\"")
+
+
+
+def depClosure2(conf, deps, ignoreExternal):
+	ret=[]	
+	gray=set(deps)
+	black=set()
+	while len(gray)>0:
+		for lib in conf["libraries"]:
+			if lib["name"] in gray:
+				gray.remove(lib["name"])
+				black.add(lib["name"])
+				if not(ignoreExternal) or not(lib["external"]):
+					ret.append((lib, []))
+					lib_deps=lib["deps"]
+					for lib_dep in lib_deps:
+						if not lib_dep in black:
+							gray.add(lib_dep)
+	return ret
+
+def depCompare(a, b):
+	if a[0] in b[1]:
+		return 1
+	elif b[0] in a[1]:
+		return -1
+	else:
+		return 0
+
+def depClosureStr(req_deps, deps):
+	ret="depClosure("+str(req_deps)+") ="
+	for lib in deps:
+		ret=ret+" "+lib[0]["name"]+"<"
+		for x in lib[1]:
+			ret=ret+" "+x[0]["name"]
+		ret=ret+" >"
+	return ret
+
+def depClosure(conf, req_deps, ignoreExternal):
+	deps=depClosure2(conf, req_deps, ignoreExternal)
+	for lib in deps:
+		lib[1].extend(depClosure2(conf, lib[0]["deps"], ignoreExternal))
+#	print depClosureStr(req_deps, deps)
+#	deps.sort(depCompare)
+#	print depClosureStr(req_deps, deps)
+	ret=[]	
+	for lib in deps:
+		ret.append(lib[0]["name"])
+#	print "\n"
+	return ret
+
+def gatherIncludeDirs(conf, ctx, deps):
+	ret=[]
+	aux={}
+	for lib in conf["libraries"]:
+		if lib["name"] in deps:
+			for file in lib["header"]["files"]:
+				if file["install"] is not None:
+					dir=os.path.dirname(file["path"])
+					dir=os.path.abspath(dir.rstrip(file["install"]))
+					dir=os.path.relpath(dir, ctx["base"])
+					if dir not in aux:
+						aux[dir]=None
+						ret.append(dir)
+#	sys.stderr.write ret
+	return ret
+
+def gatherSources(conf, ctx, lib):
+	sources=[]
+	for file in lib["source"]["files"]:
+		rel_source=os.path.relpath(file["path"], ctx["base"])
+		sources.append((rel_source, file))
+	return sources
+
+#def generateOBJS(conf, ctx, lib, out, obj_dir, cppflags):
+#	objs=[]
+#	for file in lib["source"]["files"]:
+#		rel_source=os.path.relpath(file["path"], ctx["base"])
+#		rel_obj=os.path.join(obj_dir, os.path.splitext(rel_source)[0]+".o")
+#		out_dir=os.path.dirname(rel_obj)
+#		out.write(rel_obj+": "+rel_source+"\n")
+#		out.write("\t@mkdir -p "+out_dir+"\n")
+#		specific=""
+#		if file["ext"]=="c":
+#			specific ="$(CFLAGS_C) "
+#		elif file["ext"]=="cpp":
+#			specific ="$(CFLAGS_CPP) "
+#		out.write("\t$(CC) -c $(CFLAGS) "+ specific +"$(CPPFLAGS)"+cppflags+" "+ rel_source+" -o "+rel_obj+"\n")
+#		objs.append(rel_obj)
+#	return objs
+
+def generateDEPS(conf, ctx, lib, out, obj_dir, cppflags, filename):
+	for file in lib["source"]["files"]:
+		rel_source=os.path.relpath(file["path"], ctx["base"])
+		specific=""
+		if file["ext"]=="c":
+			specific ="$(CFLAGS_C) "
+		elif file["ext"]=="cpp":
+			specific ="$(CFLAGS_CPP) "
+		out.write("\tmakedepend -a -f"+filename+" $(CPPFLAGS)"+cppflags+" "+ rel_source+"\n")
+
+def generateCPPFLAGS(conf, ctx, lib, build_dir):
+	cppflags=""
+	for define in lib["defines"]:
+		if lib["defines"][define] is None:
+			cppflags=cppflags+" -D"+define
+		else:
+			cppflags=cppflags+" -D"+define+"="+lib["defines"][define]
+	for dir in lib["header"]["includes"]:
+		abs_dir=os.path.abspath(dir)
+		rel_dir=os.path.relpath(abs_dir, os.path.join(ctx["base"], build_dir))
+#		sys.stderr.write("abs_dir="+str(abs_dir)+" build_dir="+os.path.join(ctx["base"], build_dir)+" rel_dir="+str(rel_dir))
+		cppflags=cppflags+" -I"+rel_dir
+	dep_closure=depClosure(conf, lib["deps"], False)
+	dep_dirs=gatherIncludeDirs(conf, ctx, dep_closure)
+	for dir in dep_dirs:
+		abs_dir=os.path.abspath(dir)
+		rel_dir=os.path.relpath(abs_dir, os.path.join(ctx["base"], build_dir))
+#		sys.stderr.write("abs_dir="+str(abs_dir)+" build_dir="+os.path.join(ctx["base"], build_dir)+" rel_dir="+str(rel_dir))
+		cppflags=cppflags+" -I"+rel_dir
+	for dep_lib in conf["libraries"]:
+		if dep_lib["name"] in ctx["externals"]:
+			ext_lib=ctx["externals"][dep_lib["name"]]
+			if "external" in ext_lib and ext_lib["external"]:						
+				if "cppflags" in ext_lib:
+					cppflags=cppflags+" "+ext_lib["cppflags"]
+
+	return cppflags
+
+
+def generateVCXPROJ(conf, ctx, lib, type):
+	filename=os.path.abspath("win32\\"+lib["name"]+"\\"+lib["name"]+".vcxproj")
+	filepath=os.path.dirname(filename)
+	prj_uuid=lib["uuid"]
+	sys.stderr.write("generating "+filename+"\n")
+	try:
+		os.makedirs(os.path.dirname(filename))
+	except OSError:
+		pass
+
+	out=open(filename, "w")
+	out.write("<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n");
+        out.write("<ItemGroup Label=\"ProjectConfigurations\">\n");
+        out.write(" <ProjectConfiguration Include=\"Debug|Win32\">\n");
+        out.write("   <Configuration>Debug</Configuration>\n");
+        out.write("   <Platform>Win32</Platform>\n");
+        out.write(" </ProjectConfiguration>\n");
+        out.write("<ProjectConfiguration Include=\"Release|Win32\">\n");
+        out.write("   <Configuration>Release</Configuration>\n");
+        out.write("   <Platform>Win32</Platform>\n");
+        out.write("</ProjectConfiguration>\n");
+	out.write("</ItemGroup>\n");
+        out.write("<PropertyGroup Label=\"Globals\">\n");
+        out.write("    <ProjectGuid>{"+str(prj_uuid)+"}</ProjectGuid>\n");
+        out.write("    <Keyword>Win32Proj</Keyword>\n");
+        out.write("    <RootNamespace>"+lib["name"]+"</RootNamespace>\n");
+        out.write("</PropertyGroup>\n");
+        out.write("<Import Project=\"$(VCTargetsPath)\Microsoft.Cpp.default.props\" />\n");
+        out.write("  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n");
+        out.write("    <ConfigurationType>"+type+"</ConfigurationType>\n");
+        out.write("    <UseDebugLibraries>true</UseDebugLibraries>\n");
+        out.write("    <CharacterSet>Unicode</CharacterSet>\n");
+        out.write("  </PropertyGroup>\n");
+        out.write("  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n");
+        out.write("    <ConfigurationType>"+type+"</ConfigurationType>\n");
+        out.write("    <UseDebugLibraries>false</UseDebugLibraries>\n");
+        out.write("    <WholeProgramOptimization>true</WholeProgramOptimization>\n");
+        out.write("    <CharacterSet>Unicode</CharacterSet>\n");
+        out.write("  </PropertyGroup>\n");
+        out.write("<Import Project=\"$(VCTargetsPath)\Microsoft.Cpp.props\" />\n");
+        out.write("<ImportGroup Label=\"ExtensionSettings\" />\n");
+        out.write("<ImportGroup Label=\"PropertySheets\" />\n");
+        out.write("<PropertyGroup Label=\"UserMacros\" />\n");
+        out.write("<PropertyGroup />\n");
+        out.write("<ItemDefinitionGroup>\n");
+	out.write("<ClCompile>\n");
+	dep_closure=depClosure(conf, lib["deps"], False)
+	cpp_defs="WIN32;"
+	for define in lib["defines"]:
+		if lib["defines"][define] is None:
+			cpp_defs=cpp_defs+define+";"
+		else:
+			cpp_defs=cpp_defs+define+"="+lib["defines"][define]+";"
+	for dep in dep_closure:
+		for dep_lib in conf["libraries"]:
+			if dep_lib["name"]==dep and not isExcluded(conf, ctx, dep):
+				for define in dep_lib["exports"]:
+					if dep_lib["exports"][define] is None:
+						cpp_defs=cpp_defs+define+";"
+					else:
+						cpp_defs=cpp_defs+define+"="+dep_lib["defines"][define]+";"
+	cpp_defs=cpp_defs+"_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)"
+	out.write("<PreprocessorDefinitions>"+cpp_defs+"</PreprocessorDefinitions>\n" )
+	AdditionalIncludeDirectories=""
+	for dir in lib["header"]["includes"]:
+		AdditionalIncludeDirectories=AdditionalIncludeDirectories+os.path.relpath(os.path.abspath(dir), filepath)+";"	
+	dep_dirs=gatherIncludeDirs(conf, ctx, dep_closure)
+	for dir in dep_dirs:
+		abs_path=os.path.relpath(os.path.abspath(dir), filepath)
+		AdditionalIncludeDirectories=AdditionalIncludeDirectories+abs_path+";"
+	AdditionalIncludeDirectories=AdditionalIncludeDirectories+"%(AdditionalIncludeDirectories)"
+	out.write("<AdditionalIncludeDirectories>"+AdditionalIncludeDirectories+"</AdditionalIncludeDirectories>\n")
+	if "c99"==lib["mode"]:
+		out.write("<CompileAs>CompileAsCpp</CompileAs>\n");
+	if ""!=lib["align"]:
+		out.write("<StructMemberAlignment>"+lib["align"]+"Byte</StructMemberAlignment>\n");
+	out.write("</ClCompile>\n");
+	if "Application"==type:
+		out.write("<Link>\n");
+		out.write("<AdditionalDependencies>")
+		if ctx["platform"] in conf["platforms"]:
+			ext_libs=conf["platforms"][ctx["platform"]]["libs"]
+		else:
+			ext_libs={}
+#		sys.stderr.write ext_libs
+		for ext_lib in ext_libs:
+#			sys.stderr.write ext_lib
+			out.write(ext_lib+";")
+		out.write("%(AdditionalDependencies)</AdditionalDependencies> \n")
+		out.write("</Link>\n");
+        out.write("</ItemDefinitionGroup>\n");
+
+
+	out.write("<ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n")
+	out.write("<ClCompile>\n");
+	out.write("<WarningLevel>Level3</WarningLevel>\n")
+	out.write("<Optimization>Disabled</Optimization>\n")
+	out.write("<DisableSpecificWarnings>4996</DisableSpecificWarnings>\n")
+	out.write("</ClCompile>\n");
+	if "Application"==type:
+		out.write("<Link>\n");
+		out.write("<GenerateDebugInformation>true</GenerateDebugInformation>\n")
+		out.write("<SubSystem>Console</SubSystem>\n")
+		out.write("</Link>\n");	
+        out.write("</ItemDefinitionGroup>\n");
+
+	out.write("<ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n")
+	out.write("<ClCompile>\n")
+	out.write("<Optimization>MaxSpeed</Optimization>\n")
+	out.write("<DisableSpecificWarnings>4996</DisableSpecificWarnings>\n")
+	out.write("<FunctionLevelLinking>true</FunctionLevelLinking> \n")
+	out.write("<IntrinsicFunctions>true</IntrinsicFunctions> \n")
+	out.write("</ClCompile>\n");
+	if "Application"==type:
+		out.write("<Link>\n");
+		out.write("<GenerateDebugInformation>false</GenerateDebugInformation>\n")
+		out.write("<SubSystem>Console</SubSystem>\n")
+		out.write("<EnableCOMDATFolding>true</EnableCOMDATFolding>\n")
+		out.write("<OptimizeReferences>true</OptimizeReferences>\n")
+		out.write("</Link>\n");	
+        out.write("</ItemDefinitionGroup>\n");
+
+	out.write("<ItemGroup>\n");
+        for file in lib["header"]["files"]:
+		if "h"==file["ext"]:
+			out.write("  <ClInclude Include=\""+os.path.relpath(file["path"], filepath)+"\"/>\n");
+        out.write("</ItemGroup>\n");
+        out.write("<ItemGroup>\n");
+        for file in lib["source"]["files"]:
+		if "cpp"==file["ext"] or "c"==file["ext"] or "s"==file["ext"]:
+			out.write("  <ClCompile Include=\""+os.path.relpath(file["path"], filepath)+"\">\n");
+			out.write("  </ClCompile>\n");
+        out.write("</ItemGroup>\n");
+        out.write("<ItemGroup>\n");
+	for dep in dep_closure:
+		for dep_lib in conf["libraries"]:
+			if dep_lib["name"]==dep and not isExcluded(conf, ctx, dep_lib["name"]):
+				out.write("<ProjectReference Include=\"../"+dep_lib["name"]+"/"+dep_lib["name"]+".vcxproj\">\n")
+				out.write("<Project>{"+str(dep_lib["uuid"])+"}</Project>\n")
+				out.write("</ProjectReference>\n")
+        out.write("</ItemGroup>\n")
+        out.write("<Import Project=\"$(VCTargetsPath)\Microsoft.Cpp.targets\" />\n");
+        out.write("<ImportGroup Label=\"ExtensionTargets\" />\n");
+        out.write("</Project>\n");
+	out.close()
+
+def writeProject(out, solution_uuid, lib):
+	out.write("Project(\"{"+str(solution_uuid)+"}\") = \""+lib["name"]+"\", \""+lib["name"]+"\\"+lib["name"]+".vcxproj\", \"{"+str(lib["uuid"])+"}\"\n")
+	out.write("EndProject\n")
+
+def generatePlatformList(conf, ctx):
+	add=[]
+	for platform in conf["platforms"]:
+		if platformSubseteqTest(ctx["platform"], platform):
+			add.append(platform)
+	add.sort(platformCompare)
+	return add
+
+def generateConfiguration(ctx, includes, platform):
+	conf={ "libraries": [], "tools": [], "platforms": {}, "mapping": {}, "format": {} }
+	ctx["platform"]=platform
+	for include in includes:
+		parseConfiguration(conf, include, ctx)
+	if ctx["platform"] not in conf["platforms"]:	
+		add=generatePlatformList(conf, ctx);
+		if len(add)>0:
+			conf["platforms"][ctx["platform"]]=conf["platforms"][add[0]]
+	return conf
+
+def generateWin32(ctx, source):
+	platform=ctx["platforms"][0]
+	conf=generateConfiguration(ctx, [source], platform)
+#	sys.stderr.write conf
+        sys.stderr.write("generate win32 project")
+	for lib in conf["libraries"]:
+		if not isExcluded(conf, ctx, lib["name"]):
+			generateVCXPROJ(conf, ctx, lib, "StaticLibrary")
+	for tool in conf["tools"]:
+		if not isExcluded(conf, ctx, tool["name"]):
+			generateVCXPROJ(conf, ctx, tool, "Application")
+	solution_file=os.path.abspath("win32\\solution.sln")
+	solution_uuid=uuid.uuid5(uuid.NAMESPACE_URL, solution_file)
+	out=open(solution_file, "w")
+	out.write("\n")
+	out.write("Microsoft Visual Studio Solution File, Format Version 11.00\n")
+	for lib in conf["libraries"]:
+		if not isExcluded(conf, ctx, lib["name"]):
+			writeProject(out, solution_uuid, lib)
+	for tool in conf["tools"]:
+		if not isExcluded(conf, ctx, tool["name"]):
+			writeProject(out, solution_uuid, tool)
+	out.write("\n")
+	out.close()
+
+
+def writeSourceRules(conf, ctx, lib_type, out, lib, build_dir):
+	dirs={}
+	sources=gatherSources(conf, ctx, lib)
+	out.write("objs_"+lib["name"]+"=\\\n")
+	for source in sources:
+		out.write("     $(BUILD_DIR)/"+os.path.splitext(source[0])[0]+".o\\\n")
+		dirs[os.path.dirname(source[0])]=None
+	out.write("     \n")
+	out.write(lib["name"]+"_includes="+generateCPPFLAGS(conf, ctx, lib, build_dir)+"\n")
+	out.write("\n")
+	includes="$("+lib["name"]+"_includes)"
+	lib_type_flags=""
+	if lib_type=="shared":
+		if platformSubseteqTest(ctx["platform"], "linux-*-gcc-*"):
+			lib_type_flags=" -fPIC -DPIC"
+		elif platformSubseteqTest(ctx["platform"], "darwin-*-gcc-*"):
+			lib_type_flags=" -fno-common"
+	# write special rules
+	for source in sources:
+		file=source[1]
+		if "x" in file:
+			special="-x "+file["x"]+" "
+			out.write("$(BUILD_DIR)/"+os.path.splitext(source[0])[0]+".o: $(SRC_DIR)/"+source[0]+"\n")
+			out.write("\t@mkdir -p $(dir $@)\n")
+			out.write("\t$(CC) $(CFLAGS) $(CFLAGS_C) $(CPPFLAGS) "+special+includes+lib_type_flags+" -c \"$<\" -o \"$@\"\n")
+	# write generic rules
+	for dir in dirs:
+		for ext in EXT_MAPPING:
+			if EXT_MAPPING[ext]=='c' or EXT_MAPPING[ext]=='s':
+				out.write("$(BUILD_DIR)/"+dir+"/%.o: $(SRC_DIR)/"+dir+"/%"+ext+"\n")
+				out.write("\t@mkdir -p $(dir $@)\n")
+				out.write("\t$(CC) $(CFLAGS) $(CFLAGS_C) $(CPPFLAGS) "+includes+lib_type_flags+" -c \"$<\" -o \"$@\"\n")
+				out.write("\n")
+			elif EXT_MAPPING[ext]=='cpp':
+				out.write("$(BUILD_DIR)/"+dir+"/%.o: $(SRC_DIR)/"+dir+"/%"+ext+"\n")
+				out.write("\t@mkdir -p $(dir $@)\n")
+				out.write("\t$(CC) $(CFLAGS) $(CFLAGS_CPP) $(CPPFLAGS) "+includes+lib_type_flags+" -c \"$<\" -o \"$@\"\n")
+				out.write("\n")
+
+def writeMakefileFlags(conf, ctx, out):
+	platform=ctx["platform"]
+	out.write("CC="+conf["platforms"][platform]["cc"]+"\n");
+	out.write("AR="+conf["platforms"][platform]["ar"]+"\n");
+	out.write("CFLAGS="+conf["platforms"][platform]["cflags"]+"\n")
+	out.write("CFLAGS_C="+conf["platforms"][platform]["cflags_c"]+"\n")
+	out.write("CFLAGS_CPP="+conf["platforms"][platform]["cflags_cpp"]+"\n")
+	out.write("CPPFLAGS="+conf["platforms"][platform]["cppflags"]+"\n");
+	out.write("LDFLAGS="+conf["platforms"][platform]["ldflags"]+"\n");
+
+def getSharedExt(conf, ctx):
+	if platformSubseteqTest(ctx["platform"], "darwin-*-gcc-*"):
+		return ".dylib"
+	else:
+		return ".so"
+
+def generateExtLDFlags(conf, ctx):
+	ext_ldflags=""
+	for dep_lib in conf["libraries"]:
+		if dep_lib["name"] in ctx["externals"]:
+			ext_lib=ctx["externals"][dep_lib["name"]]
+			if "external" in ext_lib and ext_lib["external"]:						
+				if "ldflags" in ext_lib:
+					ext_ldflags=ext_ldflags+" "+ext_lib["ldflags"]
+	return ext_ldflags
+
+def generateLDFlags(conf, ctx, lib_type, initial_deps, exclude_deps, lib_form):
+	ret=""
+	deps=depClosure(conf, initial_deps, True)
+	for dep in deps:
+		if not(dep in exclude_deps):
+			if lib_type=="static":
+				ret=ret+" $(BUILD_DIR)/lib"+dep+".a"
+			if lib_type=="shared":
+				if lib_form:
+					ret=ret+" -L$(BUILD_DIR) -l"+dep
+				else:
+					ret=ret+" $(BUILD_DIR)/lib"+dep+getSharedExt(conf, ctx)
+
+	return ret
+
+
+def generateLibraryMakefile(conf, ctx, lib_type, lib, filename, build_dir, src_dir):
+	sys.stderr.write("generating "+filename+"\n")
+	if not os.path.exists(os.path.dirname(filename)):
+    		os.makedirs(os.path.dirname(filename))
+	out=open(filename, "w")
+	out.write("# Generated.\n")
+	# compiler flags
+	writeMakefileFlags(conf, ctx, out)
+	out.write("BUILD_DIR=.\n")
+	out.write("SRC_DIR="+src_dir+"\n")
+	out.write("\n")
+	out.write(".PHONY: all clean\n")
+	out.write("\n")
+	out.write("# library "+lib["name"]+"\n")
+	out.write("all:")
+	if lib_type=="static":
+		out.write(" $(BUILD_DIR)/lib"+lib["name"]+".a")
+	if lib_type=="shared":
+		out.write(" $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx))
+	out.write("\n\n")
+	writeSourceRules(conf, ctx, lib_type, out, lib, build_dir)
+	if lib_type=="static":
+		out.write("$(BUILD_DIR)/lib"+lib["name"]+".a: $(objs_"+lib["name"]+")\n")
+		out.write("\t$(AR) -rcs $(BUILD_DIR)/lib"+lib["name"]+".a $(objs_"+lib["name"]+")\n")
+		out.write("\n")
+	if lib_type=="shared":
+		ld_deps=generateLDFlags(conf, ctx, lib_type, lib["deps"], [lib["name"]], True)+generateExtLDFlags(conf, ctx)
+		out.write("$(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx)+": $(objs_"+lib["name"]+")\n")
+		if platformSubseteqTest(ctx["platform"], "darwin-*-gcc-*"):
+			out.write("\t$(CC) -dynamiclib -install_name lib"+lib["name"]+getSharedExt(conf, ctx)+" -o $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx)+" $(objs_"+lib["name"]+")"+ld_deps+"\n")
+		else:
+			out.write("\t$(CC) -shared -Wl,-soname,lib"+lib["name"]+getSharedExt(conf, ctx)+" -Wl,-z,defs  -fPIC -o $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx)+" $(objs_"+lib["name"]+")"+ld_deps+" -lc\n")
+			out.write("\tstrip --remove-section=.comment --remove-section=.note --strip-unneeded $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx))
+		out.write("\n")
+	out.write("clean:\n")
+	out.write("\trm -rf $(BUILD_DIR)/lib"+lib["name"]+".a $(BUILD_DIR)/lib"+lib["name"]+getSharedExt(conf, ctx)+" $(objs_"+lib["name"]+")\n")
+	out.close()
+	
+def generateLibraryInclude(conf, ctx, lib, filename, build_dir, src_dir):
+	sys.stderr.write("generating "+filename+"\n")
+	if not os.path.exists(os.path.dirname(filename)):
+    		os.makedirs(os.path.dirname(filename))
+	ret=[]
+	lib_deps=lib["deps"]
+	lib_deps.append(lib["name"])
+#	out.write("deps="+str(lib["deps"])+"\n");
+	dep_closure=depClosure(conf, lib_deps, False)
+	dep_dirs=gatherIncludeDirs(conf, ctx, dep_closure)
+	for dep in dep_dirs:
+		dep_dir=os.path.join(ctx["base"], str(dep))
+		if dep_dir in conf["mapping"]:
+			dep_dir=conf["mapping"][dep_dir]
+		if dep_dir in conf["format"]:
+			ln_src=os.path.join(build_dir, "include", os.path.relpath(conf["format"][dep_dir], ctx["base"]).format(platform="platform").replace(os.sep, "_"))
+			ln_dst=os.path.join(src_dir, dep)
+			if os.path.exists(ln_src):
+				os.remove(ln_src)
+			print "symlink("+ln_dst+", "+ln_src+")"+str(os.path.exists(ln_src))
+			os.symlink(ln_dst, ln_src)
+			ret.append(ln_src)
+		else:
+			ret.append(dep)
+
+	out=open(filename, "w")
+	for file in ret:
+		out.write(file+"\n")
+	out.close()
+
+
+def generateToolMakefile(conf, ctx, lib_type, tool, filename, build_dir, src_dir):
+	sys.stderr.write("generating "+filename+"\n")
+	if not os.path.exists(os.path.dirname(filename)):
+    		os.makedirs(os.path.dirname(filename))
+	out=open(filename, "w")
+	out.write("# Generated.\n")
+	# compiler flags
+	writeMakefileFlags(conf, ctx, out)
+	out.write("BUILD_DIR=.\n")
+	out.write("SRC_DIR="+src_dir+"\n")
+	out.write("\n")
+	out.write(".PHONY: all clean\n")
+	out.write("\n")
+	out.write("# tool "+tool["name"]+"\n")
+	out.write("all: $(BUILD_DIR)/"+ tool["name"]+"\n\n")
+	writeSourceRules(conf, ctx, "static", out, tool, build_dir)
+	out.write(tool["name"]+"_ld="+generateLDFlags(conf, ctx, lib_type, tool["deps"], [], False)+"\n")
+#	deps=depClosure(conf, tool["deps"], True)
+#	for dep in deps:
+#		if lib_type=="static":
+#			out.write(" $(BUILD_DIR)/lib"+ dep +".a")	
+#		if lib_type=="shared":
+#			out.write(" $(BUILD_DIR)/lib"+ dep +getSharedExt(conf, ctx))	
+#	out.write("\n")
+	ext_ldflags=generateExtLDFlags(conf, ctx)
+#	ext_ldflags=""
+#	for dep_lib in conf["libraries"]:
+#		if dep_lib["name"] in ctx["externals"]:
+#			ext_lib=ctx["externals"][dep_lib["name"]]
+#			if "external" in ext_lib and ext_lib["external"]:						
+#				if "ldflags" in ext_lib:
+#					ext_ldflags=ext_ldflags+" "+ext_lib["ldflags"]
+
+	out.write("$(BUILD_DIR)/"+tool["name"]+": $(objs_"+tool["name"]+") $("+tool["name"]+"_ld)\n")			
+	static_flag=""
+	if lib_type=="static" and platformSubseteqTest(ctx["platform"], "linux-*-gcc-*"):
+		static_flag=" --static"
+	out.write("\t$(CC) $(CFLAGS) $(CPPFLAGS) -o $(BUILD_DIR)/"+tool["name"]+" $(objs_"+tool["name"]+") "+generateLDFlags(conf, ctx, lib_type, tool["deps"], [], True)+ ext_ldflags+" $(LDFLAGS)\n")
+	out.write("\n")
+	out.write("clean:\n")
+	out.write("\trm -f $(BUILD_DIR)/"+tool["name"]+" $(objs_"+tool["name"]+")\n")
+
+
+def generateTypedMakefile(conf, ctx, lib_type):
+	obj_dir=os.path.join("build", ctx["platform"], lib_type)
+	filename=os.path.join(obj_dir, "Makefile")
+	sys.stderr.write("generating "+filename+"\n")
+	if not os.path.exists(os.path.dirname(filename)):
+    		os.makedirs(os.path.dirname(filename))
+	out=open(filename, "w")
+	out.write("# Generated.\n")
+
+	# generate phony targets
+	out.write(".PHONY: all clean tools dep")
+	for lib in conf["libraries"]:
+		if not lib["external"]:
+			out.write(" "+lib["name"])
+	for tool in conf["tools"]:
+		out.write(" "+tool["name"])
+	out.write("\n")
+	# all
+	out.write("all:")
+	for lib in conf["libraries"]:
+		if not lib["external"]:
+			out.write(" "+lib["name"])
+	out.write(" tools\n")
+	# tools
+	out.write("tools:")
+	for tool in conf["tools"]:
+		out.write(" "+tool["name"])
+	out.write("\n")
+
+	# generate libs
+	for lib in conf["libraries"]:
+		if not lib["external"]:
+			makefile=os.path.join(obj_dir, "Makefile."+lib["name"])
+			generateLibraryMakefile(conf, ctx, lib_type, lib, makefile, obj_dir, os.path.join("..", "..", ".."))
+			libincludefile=os.path.join(obj_dir, "include", lib["name"]+".inc")
+			generateLibraryInclude(conf, ctx, lib, libincludefile, obj_dir, os.path.join("..", "..", "..", ".."))
+			out.write(lib["name"]+":")
+			deps=depClosure(conf, lib["deps"], True)
+			for dep in deps:
+				if lib["name"]!=dep:
+					out.write(" "+dep)
+			out.write("\n")
+			out.write("\t$(MAKE) -f "+"Makefile."+lib["name"]+"\n\n")
+	
+	# generate tools
+	for tool in conf["tools"]:
+		makefile=os.path.join(obj_dir, "Makefile."+tool["name"])
+		generateToolMakefile(conf, ctx, lib_type, tool, makefile, obj_dir, os.path.join("..", "..", ".."))
+		deps=depClosure(conf, tool["deps"], True)
+		out.write(tool["name"]+":")
+		for dep in deps:
+			if tool["name"]!=dep:
+				out.write(" "+dep)
+		out.write("\n")
+		out.write("\t$(MAKE) -f "+"Makefile."+ tool["name"]+"\n\n")
+
+	out.write("clean:\n")
+	for lib in conf["libraries"]:
+		if not lib["external"]:
+			out.write("\t$(MAKE) -f "+"Makefile."+lib["name"]+" clean\n")
+	for tool in conf["tools"]:
+		out.write("\t$(MAKE) -f "+"Makefile."+tool["name"]+" clean\n")
+
+
+#	out.write("dep:\n")
+#	for lib in conf["libraries"]:
+#		generateDEPS(conf, ctx, lib, out, obj_dir, generateCPPFLAGS(conf, ctx, lib), filename)
+#	for tool in conf["tools"]:
+#		generateDEPS(conf, ctx, tool, out, obj_dir, generateCPPFLAGS(conf, ctx, tool), filename)
+
+	out.write("package: all\n")
+	out.write("\tcd ../../.. && ./generate.py --include Makefile.xml");
+	for ext_lib in ctx["externals"]:
+		if ctx["externals"][ext_lib]["external"]:
+			name=ext_lib
+			if "xml"==ext_lib:
+				name="libxml"
+			out.write(" --with-"+name+"=yes")
+			if "cppflags" in ctx["externals"][ext_lib]:
+				out.write(" --with-"+name+"-cppflags=\""+ctx["externals"][ext_lib]["cppflags"]+"\"")
+			if "ldflags" in ctx["externals"][ext_lib]:
+				out.write(" --with-"+name+"-ldflags=\""+ctx["externals"][ext_lib]["ldflags"]+"\"")
+	out.write(" --package package_"+lib_type+".zip --type "+lib_type)
+	out.write(" --config-dir "+ctx["config"]+" "+ctx["platform"])
+	out.write("\n")
+
+	obj_dir=os.path.join(ctx["base"], "build", ctx["platform"], lib_type)
+	tool_ext=""
+	if lib_type=="static":
+		lib_ext=".a"
+	else:
+		lib_ext=getSharedExt(conf, ctx)
+	lib_prefix="lib"
+	base="$(DESTDIR)/usr/"
+	out.write("install: all\n")
+	for lib in conf["libraries"]:
+		if not lib["external"] and not isExcluded(conf, ctx, lib["name"]):
+			for include in lib["header"]["files"]:
+				if None!=include["install"]:
+					target=base+"include/"
+					if len(include["install"])>0:
+						target=target+include["install"]+"/"
+					target=target+os.path.split(include["path"])[1]
+					out.write("\t@mkdir -p "+os.path.dirname(target)+"\n")
+					out.write("\t@cp "+include["path"]+" "+target+"\n")
+			target=base+"lib/"+lib_prefix+lib["name"]+lib_ext
+			out.write("\t@mkdir -p "+os.path.dirname(target)+"\n")
+			if lib_type=="shared":
+				out.write("\t@cp "+os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext)+" "+target+".1\n")
+				out.write("\tldconfig -v -n "+os.path.dirname(target)+"\n")
+			else:
+				out.write("\t@cp "+os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext)+" "+target+"\n")
+	for tool in conf["tools"]:
+		if not isExcluded(conf, ctx, tool["name"]):
+			target=base+"bin/"+tool["name"]+tool_ext
+			out.write("\t@mkdir -p "+os.path.dirname(target)+"\n")
+			out.write("\t@cp "+os.path.join(obj_dir, tool["name"]+tool_ext)+" "+target+"\n")
+	target=base+"lib/pkgconfig/libopc.pc"
+	out.write("\t@mkdir -p "+os.path.dirname(target)+"\n")	
+	out.write("\t@cp "+os.path.join(ctx["base"], "config", "libopc.pc")+" "+target+"\n")
+	out.close()
+
+
+def generateTypedMakefiles(ctx, source, lib_types):
+	for platform in ctx["platforms"]:
+		conf=generateConfiguration(ctx, [source], platform)
+		if ctx["platform"] in conf["platforms"]:	
+			for lib_type in lib_types:		
+				generateTypedMakefile(conf, ctx, lib_type)
+		else:
+			parseError("platform "+ctx["platform"]+" is unknown.")
+			sys.stderr.write("available platforms:");
+			for platform in conf["platforms"]:
+				sys.stderr.write(platform+"\n")
+	out=open("Makefile", "w")
+	out.write(".PHONY: all clean");
+	for platform in ctx["platforms"]:
+		for lib_type in lib_types:		
+			out.write(" "+platform+"."+lib_type);
+	for lib_type in lib_types:		
+		out.write(" "+lib_type);
+	out.write("\n");
+	out.write("all:");
+	for lib_type in lib_types:		
+		out.write(" "+lib_type);
+	out.write("\n");
+
+	for lib_type in lib_types:		
+		out.write(lib_type+":");
+		for platform in ctx["platforms"]:
+			out.write(" "+platform+"."+lib_type);
+		out.write("\n");
+
+	for lib_type in lib_types:		
+		for platform in ctx["platforms"]:
+			out.write(platform+"."+lib_type+": build"+os.sep+platform+os.sep+lib_type+os.sep+"Makefile\n");
+			out.write("\t@$(MAKE) -C build"+os.sep+platform+os.sep+lib_type+"\n");
+	out.write("clean:\n")
+	for lib_type in lib_types:		
+		for platform in ctx["platforms"]:
+			out.write("\t@$(MAKE) -C build"+os.sep+platform+os.sep+lib_type+" clean\n");	
+	out.write("package:\n")
+	for lib_type in lib_types:		
+		for platform in ctx["platforms"]:
+			out.write("\t@$(MAKE) -C build"+os.sep+platform+os.sep+lib_type+" package\n")
+	out.write("install:\n")
+	for lib_type in lib_types:		
+		for platform in ctx["platforms"]:
+			out.write("\t@$(MAKE) -C build"+os.sep+platform+os.sep+lib_type+" install\n")
+	out.close()
+
+def dumpEnvironment(ctx, includes, platform):
+	conf=generateConfiguration(ctx, includes, platform)
+	if platform in conf["platforms"]:			
+		p=conf["platforms"][platform]
+#		print(str(p))
+		host=""
+		if "host" in p:
+			host="HOST=\""+p["host"]+"\" "
+		sys.stdout.write("export CC=\""+p["cc"]+"\" "+
+			 "export AR=\""+p["ar"]+"\" "+
+			 "export LD=\""+p["ld"]+"\" "
+			 "export CPPFLAGS=\""+p["cppflags"]+"\" "
+			 "export CFLAGS=\""+p["cflags"]+"\" "+
+			 host
+			)
+	else:
+		parseError("platform "+platform+" is unknown.")
+		sys.stderr.write("available platforms:");
+		for platform in conf["platforms"]:
+			sys.stderr.write(platform)	
+
+def set_external_flag(ctx, lib, flag, value):
+#	sys.stderr.write("SETTING "+lib+" "+flag+" "+str(value)+"\n")
+	if lib in ctx["externals"]:
+		ctx["externals"][lib][flag]=value
+	else:
+		ctx["externals"][lib]={flag: value}
+
+def is_external(ctx, lib):
+	if lib in ctx["externals"]:
+		if "external" in ctx["externals"][lib]:
+			return ctx["externals"][lib]["external"]
+		else:
+			return False
+	else:
+		return False
+
+
+def generateZipPackage(ctx, source, lib_type, install_zip):
+	zip=zipfile.ZipFile(install_zip, 'w', zipfile.ZIP_DEFLATED)
+	base=os.path.splitext(install_zip)[0]+"/"
+	platform=ctx["platforms"][0]
+	conf=generateConfiguration(ctx, [source], platform)
+	if platformSubseteqTest(ctx["platforms"][0], "win32-*-*"):
+		obj_dir=os.path.join("win32", ctx["platform"].split('-')[1])
+		tool_ext=".exe"
+		lib_exts=[".lib"]
+		if (lib_type=="shared"):
+			shared_exts.append(".dll")		
+		lib_prefix=""
+	else:
+		obj_dir=os.path.join("build", ctx["platform"], lib_type)
+		tool_ext=""
+		if lib_type=="shared":
+			lib_exts=[".dylib"]
+		else:
+			lib_exts=[".a"]
+		lib_prefix="lib"
+	for lib in conf["libraries"]:
+		if not lib["external"] and not isExcluded(conf, ctx, lib["name"]):
+			for include in lib["header"]["files"]:
+				if None!=include["install"]:
+					target=base+"include/"
+					if len(include["install"])>0:
+						target=target+include["install"]+"/"
+					target=target+os.path.split(include["path"])[1]
+					zip.write(include["path"], target)
+			for lib_ext in lib_exts:
+				target=base+"lib/"+lib_prefix+lib["name"]+lib_ext
+#				print "ADD "+os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext)
+				zip.write(os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext), target)
+	for tool in conf["tools"]:
+		if not isExcluded(conf, ctx, tool["name"]):
+			target=base+"bin/"+tool["name"]+tool_ext
+			zip.write(os.path.join(obj_dir, tool["name"]+tool_ext), target)
+	zip.write(os.path.join("third_party", "LICENSE"), base+"/LICENSE.THIRD_PARTY")
+	zip.write("LICENSE", base+"/LICENSE")
+	zip.close()
+
+
+
+def installFiles(ctx, source, lib_type, base):
+	copy_ctx=None
+	platform=ctx["platforms"][0]
+	conf=generateConfiguration(ctx, [source], platform)
+	if platformSubseteqTest(ctx["platforms"][0], "win32-*-*"):
+		obj_dir=os.path.join("win32", ctx["platform"].split('-')[1])
+		tool_ext=".exe"
+		lib_exts=[".lib"]
+		lib_prefix=""
+	else:
+		obj_dir=os.path.join("build", ctx["platform"], lib_type)
+		tool_ext=""
+		lib_exts=[".a", getSharedExt(conf, ctx)]
+		lib_prefix="lib"
+	for lib in conf["libraries"]:
+		if not lib["external"] and not isExcluded(conf, ctx, lib["name"]):
+			for include in lib["header"]["files"]:
+				if None!=include["install"]:
+					target=base+"include/"
+					if len(include["install"])>0:
+						target=target+include["install"]+"/"
+					target=target+os.path.split(include["path"])[1]
+					copyFile(copy_ctx, include["path"], target)
+			for lib_ext in lib_exts:
+				target=base+"lib/"+lib_prefix+lib["name"]+lib_ext
+				copyFile(copy_ctx, os.path.join(obj_dir, lib_prefix+lib["name"]+lib_ext), target)
+	for tool in conf["tools"]:
+		if not isExcluded(conf, ctx, tool["name"]):
+			target=base+"bin/"+tool["name"]+tool_ext
+			copyFile(copy_ctx, os.path.join(obj_dir, tool["name"]+tool_ext), target)
+	copyFile(copy_ctx, os.path.join("third_party", "LICENSE"), base+"/LICENSE.THIRD_PARTY")
+	copyFile(copy_ctx, "LICENSE", base+"/LICENSE")
+
+def usage():
+	print("usage:")
+	print(" generate [--include \"Makefile.xml\"]")
+	print("          [--config-dir \"config/\"]")
+	print("          [--print-env \"linux-release-gcc\"]")
+	print("          [--package \"xyz.zip/\"]")
+
+if __name__ == "__main__":	
+	try:
+		opts, args = getopt.getopt(sys.argv[1:], "h", ["help", "include=", "config-dir=", "print-env=", 
+			"package=", "install=", 
+			"with-zlib-cppflags=", "with-zlib-ldflags=", "with-zlib=",
+			"with-libxml-cppflags=", "with-libxml-ldflags=", "with-libxml=",
+			"type="])
+	except getopt.GetoptError, err:
+		# print help information and exit:
+		print str(err) # will print something like "option -a not recognized"
+		usage()
+		sys.exit(2)
+	ctx={ "base": os.path.abspath(os.curdir), "root": os.path.abspath(os.curdir), "platform": "?-?-?", "platforms": [], "externals": {} }
+	ctx["config"]=ctx["base"]
+	includes=[]
+	dump_env=[]
+	install_zip=None
+	target_type="static"
+	for o, a in opts:
+		if o in ("-h", "--help"):
+			usage()
+			sys.exit(0)
+		elif o in ("--include"):
+			includes.append(a)
+		elif o in ("--config-dir"):
+			ctx["config"]=os.path.join(ctx["base"], a)
+		elif o in ("--print-env"):
+			args=[]
+			dump_env=[a]
+		elif o in ("--package"):
+			install_zip=a
+		elif o in ("--install"):
+			install_files=a
+		elif o in ("--with-zlib"):
+			set_external_flag(ctx, "zlib", "external", "yes"==a)
+		elif o in ("--with-zlib-cppflags"):
+			set_external_flag(ctx, "zlib", "cppflags", a)
+		elif o in ("--with-zlib-ldflags"):
+			set_external_flag(ctx, "zlib", "ldflags", a)
+		elif o in ("--with-libxml"):
+			set_external_flag(ctx, "xml", "external", "yes"==a)
+		elif o in ("--with-libxml-cppflags"):
+			set_external_flag(ctx, "xml", "cppflags", a)
+		elif o in ("--with-libxml-ldflags"):
+			set_external_flag(ctx, "xml", "ldflags", a)
+		elif o in ("--type"):
+			target_type=a
+
+	for platform in args:
+		ctx["platforms"].append(platform)
+
+	if 1==len(ctx["platforms"]) and None!=install_zip and 1==len(includes):
+		ctx["root"]=os.path.abspath(os.path.split(includes[0])[0])
+		generateZipPackage(ctx, includes[0], target_type, install_zip)
+	elif 1==len(ctx["platforms"]) and platformSubseteqTest(ctx["platforms"][0], "win32-*-msvc-*") and 1==len(includes):
+		ctx["root"]=os.path.abspath(os.path.split(includes[0])[0])
+		generateWin32(ctx, includes[0])
+	else:
+		if is_external(ctx, "zlib") and is_external(ctx, "xml"):
+			lib_types=["static", "shared"]
+		else:
+			lib_types=["static"]
+		if not os.path.exists("build"):
+			os.makedirs("build")
+		f=open(os.path.join("build", "configure.ctx"), "w")
+		f.write(str(ctx))
+		f.close()		
+		for include in includes:
+			ctx["root"]=os.path.abspath(os.path.split(include)[0])
+			generateTypedMakefiles(ctx, include, lib_types)
+
+	for platform in dump_env:
+		dumpEnvironment(ctx, includes, platform)
+

+ 154 - 0
mce/helper.c

@@ -0,0 +1,154 @@
+#include <mce/helper.h>
+#include <libxml/xmlmemory.h>
+
+static pbool_t mceQNameLevelLookupEx(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, puint32_t *pos, pbool_t ignore_ln) {
+    puint32_t i=0;
+    puint32_t j=qname_level_set->list_items;
+    while(i<j) {
+        puint32_t m=i+(j-i)/2;
+        PASSERT(i<=m && m<j);
+        mceQNameLevel_t *q2=&qname_level_set->list_array[m];
+        int const ns_cmp=(NULL==ns?(NULL==q2->ns?0:-1):(NULL==q2->ns?+1:xmlStrcmp(ns, q2->ns)));
+        int const cmp=(ignore_ln?ns_cmp:(0==ns_cmp?xmlStrcmp(ln, q2->ln):ns_cmp));
+        if (cmp<0) { j=m; } else if (cmp>0) { i=m+1; } else { *pos=m; return PTRUE; }
+    }
+    PASSERT(i==j); 
+    *pos=i;
+    return PFALSE;
+}
+
+mceQNameLevel_t* mceQNameLevelLookup(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, pbool_t ignore_ln) {
+    puint32_t pos=0;
+    return (mceQNameLevelLookupEx(qname_level_set, ns, ln, &pos, ignore_ln)?qname_level_set->list_array+pos:NULL);
+}
+
+pbool_t mceQNameLevelAdd(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, puint32_t level) {
+    puint32_t i=0;
+    pbool_t ret=PFALSE;
+    if (!mceQNameLevelLookupEx(qname_level_set, ns, ln, &i, PFALSE)) {
+        mceQNameLevel_t *new_list_array=NULL;
+        if (NULL!=(new_list_array=(mceQNameLevel_t *)xmlRealloc(qname_level_set->list_array, (1+qname_level_set->list_items)*sizeof(*qname_level_set->list_array)))) {
+            qname_level_set->list_array=new_list_array;
+            for (puint32_t k=qname_level_set->list_items;k>i;k--) {
+                qname_level_set->list_array[k]=qname_level_set->list_array[k-1];
+            }
+            qname_level_set->list_items++;
+            PASSERT(i>=0 && i<qname_level_set->list_items);
+            memset(&qname_level_set->list_array[i], 0, sizeof(qname_level_set->list_array[i]));
+            qname_level_set->list_array[i].level=level;
+            qname_level_set->list_array[i].ln=(NULL!=ln?xmlStrdup(ln):NULL);
+            qname_level_set->list_array[i].ns=xmlStrdup(ns);
+            if (qname_level_set->max_level<level) qname_level_set->max_level=level;
+            ret=PTRUE;
+        }
+    } else {
+        ret=PTRUE;
+    }
+    return ret;
+}
+
+pbool_t mceQNameLevelCleanup(mceQNameLevelSet_t *qname_level_set, puint32_t level) {
+    if (qname_level_set->max_level>=level) {
+        qname_level_set->max_level=0;
+        puint32_t i=0;
+        for(puint32_t j=0;j<qname_level_set->list_items;j++) {
+            if (qname_level_set->list_array[j].level>=level) {
+                PASSERT(qname_level_set->list_array[j].level==level); // cleanup should be called for every level...
+                if (NULL!=qname_level_set->list_array[j].ln) xmlFree(qname_level_set->list_array[j].ln);
+                if (NULL!=qname_level_set->list_array[j].ns) xmlFree(qname_level_set->list_array[j].ns);
+            } else {
+                if (qname_level_set->list_array[j].level>qname_level_set->max_level) {
+                    qname_level_set->max_level=qname_level_set->list_array[j].level;
+                }
+                qname_level_set->list_array[i++]=qname_level_set->list_array[j];
+            }
+        }
+        qname_level_set->list_items=i;
+    }
+    PASSERT(0==level || qname_level_set->max_level<level);
+    return PTRUE;
+}
+
+
+pbool_t mceSkipStackPush(mceSkipStack_t *skip_stack, puint32_t level_start, puint32_t level_end, mceSkipState_t state) {
+    pbool_t ret=PFALSE;
+    mceSkipItem_t *new_stack_array=NULL;
+    if (NULL!=(new_stack_array=(mceSkipItem_t *)xmlRealloc(skip_stack->stack_array, (1+skip_stack->stack_items)*sizeof(*skip_stack->stack_array)))) {
+        skip_stack->stack_array=new_stack_array;
+        memset(&skip_stack->stack_array[skip_stack->stack_items], 0, sizeof(skip_stack->stack_array[skip_stack->stack_items]));
+        skip_stack->stack_array[skip_stack->stack_items].level_start=level_start;
+        skip_stack->stack_array[skip_stack->stack_items].level_end=level_end;
+        skip_stack->stack_array[skip_stack->stack_items].state=state;
+        skip_stack->stack_items++;
+        ret=PTRUE;
+    }
+    return ret;
+}
+
+void mceSkipStackPop(mceSkipStack_t *skip_stack) {
+    PASSERT(skip_stack->stack_items>0);
+    skip_stack->stack_items--;
+}
+
+mceSkipItem_t *mceSkipStackTop(mceSkipStack_t *skip_stack) {
+    return NULL!=skip_stack->stack_array && skip_stack->stack_items>0 ? &skip_stack->stack_array[skip_stack->stack_items-1] : NULL;
+}
+
+pbool_t mceSkipStackSkip(mceSkipStack_t *skip_stack, puint32_t level) {
+    return NULL!=skip_stack->stack_array && skip_stack->stack_items>0 
+        && level>=skip_stack->stack_array[skip_stack->stack_items-1].level_start 
+        && level<skip_stack->stack_array[skip_stack->stack_items-1].level_end;
+}
+
+pbool_t mceCtxInit(mceCtx_t *ctx) {
+    memset(ctx, 0, sizeof(*ctx));
+    mceCtxSuspendProcessing(ctx, _X("http://schemas.openxmlformats.org/presentationml/2006/main"), _X("extLst"));
+    return PTRUE;
+}
+
+pbool_t mceCtxCleanup(mceCtx_t *ctx) {
+
+    PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->ignorable_set.list_items);
+    PENSURE(mceQNameLevelCleanup(&ctx->ignorable_set, 0));
+    PENSURE(mceQNameLevelCleanup(&ctx->understands_set, 0));
+    PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->skip_stack.stack_items);
+    while (NULL!=mceSkipStackTop(&ctx->skip_stack)) mceSkipStackPop(&ctx->skip_stack);
+    PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->processcontent_set.list_items);
+    PENSURE(mceQNameLevelCleanup(&ctx->processcontent_set, 0));
+    PENSURE(mceQNameLevelCleanup(&ctx->suspended_set, 0));
+    PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->suspended_level);
+#if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
+    PENSURE(mceQNameLevelCleanup(&ctx->subsume_namespace_set, 0));
+    PENSURE(mceQNameLevelCleanup(&ctx->subsume_exclude_set, 0));
+    PENSURE(mceQNameLevelCleanup(&ctx->subsume_prefix_set, 0));
+#endif
+    
+    if (NULL!=ctx->ignorable_set.list_array) xmlFree(ctx->ignorable_set.list_array);
+    if (NULL!=ctx->understands_set.list_array) xmlFree(ctx->understands_set.list_array);
+    if (NULL!=ctx->skip_stack.stack_array) xmlFree(ctx->skip_stack.stack_array);
+    if (NULL!=ctx->processcontent_set.list_array) xmlFree(ctx->processcontent_set.list_array);
+    if (NULL!=ctx->suspended_set.list_array) xmlFree(ctx->suspended_set.list_array);
+#if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
+    if (NULL!=ctx->subsume_namespace_set.list_array) xmlFree(ctx->subsume_namespace_set.list_array);
+    if (NULL!=ctx->subsume_exclude_set.list_array) xmlFree(ctx->subsume_exclude_set.list_array);
+    if (NULL!=ctx->subsume_prefix_set.list_array) xmlFree(ctx->subsume_prefix_set.list_array);
+#endif
+    return PTRUE;
+}
+
+pbool_t mceCtxUnderstandsNamespace(mceCtx_t *ctx, const xmlChar *ns) {
+    return mceQNameLevelAdd(&ctx->understands_set, ns, NULL, 0);
+}
+
+pbool_t mceCtxSuspendProcessing(mceCtx_t *ctx, const xmlChar *ns, const xmlChar *ln) {
+    return mceQNameLevelAdd(&ctx->suspended_set, ns, ln, 0);
+}
+
+
+#if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
+pbool_t mceCtxSubsumeNamespace(mceCtx_t *ctx, const xmlChar *prefix_new, const xmlChar *ns_new, const xmlChar *ns_old) {
+    return mceQNameLevelAdd(&ctx->subsume_namespace_set, ns_old, ns_new, 0)
+        && mceQNameLevelAdd(&ctx->subsume_prefix_set, ns_new, prefix_new, 0);
+}
+#endif
+

+ 189 - 0
mce/helper.h

@@ -0,0 +1,189 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file mce/helper.h
+Helper functions needed by mce/textreader.h and mce/textwriter.h to implement MCE:
+- mceQNameLevelAdd(), mceQNameLevelLookup() and mceQNameLevelCleanup() maintain a set of mceQNameLevel_t tuples.
+- mceQNameLevelPush() and mceQNameLevelPopIfMatch() maintain a stack of mceQNameLevel_t tuples.
+- mceCtxInit(), mceCtxCleanup() and mceCtxUnderstandsNamespace() manage a context which holds all information needed to do MCE proprocessing.
+ */
+#include <mce/config.h>
+
+#ifndef MCE_HELPER_H
+#define MCE_HELPER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    /**
+      Tiple (ns, ln, level).
+    */
+    typedef struct MCE_QNAME_LEVEL {
+        xmlChar *ns;
+        xmlChar *ln;
+        puint32_t level;
+        puint32_t flag; // used by mceTextWriter
+    } mceQNameLevel_t;
+
+    /**
+     */
+    typedef enum MCE_SKIP_STATE_ENUM {
+        MCE_SKIP_STATE_IGNORE,
+        MCE_SKIP_STATE_ALTERNATE_CONTENT,
+        MCE_SKIP_STATE_CHOICE_MATCHED
+    } mceSkipState_t;
+
+    /**
+     Represents an intervall of levels which are "skipped" i.e. ignored.
+     */
+    typedef struct MCE_SKIP_ITEM {
+        puint32_t level_start;
+        puint32_t level_end;
+        mceSkipState_t state;
+    } mceSkipItem_t;
+
+    /**
+      Either represents a set of (ns, ln, level) triples.
+    */
+    typedef struct MCE_QNAME_LEVEL_SET {
+        mceQNameLevel_t *list_array;
+        puint32_t list_items;
+        puint32_t max_level;
+    } mceQNameLevelSet_t;
+
+    /**
+     The skip stack.
+     */
+    typedef struct MCE_SKIP_STACK {
+        mceSkipItem_t *stack_array;
+        puint32_t stack_items;
+    } mceSkipStack_t;
+
+
+    typedef enum MCE_ERROR_ENUM {
+        MCE_ERROR_NONE,
+        MCE_ERROR_XML,
+        MCE_ERROR_MUST_UNDERSTAND,
+        MCE_ERROR_VALIDATION,
+        MCE_ERROR_MEMORY
+    } mceError_t;
+
+    /**
+      Holds all information to do MCE preprocessing.
+    */
+    typedef struct MCE_CONTEXT {
+        mceQNameLevelSet_t ignorable_set;
+        mceQNameLevelSet_t understands_set;
+        mceQNameLevelSet_t processcontent_set;
+        mceQNameLevelSet_t suspended_set;
+#if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
+        mceQNameLevelSet_t subsume_namespace_set;
+        mceQNameLevelSet_t subsume_exclude_set;
+        mceQNameLevelSet_t subsume_prefix_set;
+#endif
+        mceSkipStack_t skip_stack;
+        mceError_t error;
+        pbool_t mce_disabled;        
+        puint32_t suspended_level;
+    } mceCtx_t;
+
+    /**
+      Add a new tiple (ns, ln, level) to the triple set \c qname_level_set.
+      The \c ns_sub string is optional and will not be touched.
+    */
+    pbool_t mceQNameLevelAdd(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, puint32_t level);
+
+    /**
+      Lookup a tiple (ns, ln, level) via \c ns and \c ln. If \c ignore_ln is PTRUE then the first tiple matching \c ns will be returned.
+    */
+    mceQNameLevel_t* mceQNameLevelLookup(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, pbool_t ignore_ln);
+
+    /**
+      Remove all triples (ns, ln, level) where the level greater or equal to \c level.
+    */
+    pbool_t mceQNameLevelCleanup(mceQNameLevelSet_t *qname_level_set, puint32_t level);
+
+    /**
+      Push a new skip intervall (level_start, level_end, state) on the stack \c skip_stack.
+    */
+    pbool_t mceSkipStackPush(mceSkipStack_t *skip_stack, puint32_t level_start, puint32_t level_end, mceSkipState_t state);
+
+    /**
+      Pop the intervall (ns, ln, level) from the stack \c qname_level_array.
+    */
+    void mceSkipStackPop(mceSkipStack_t *skip_stack);
+
+    /**
+     Returns top item or NULL.
+     */
+    mceSkipItem_t *mceSkipStackTop(mceSkipStack_t *skip_stack);
+
+    /**
+     Returns TRUE, if the \c level is in the top skip intervall.
+     */
+    pbool_t mceSkipStackSkip(mceSkipStack_t *skip_stack, puint32_t level);
+
+    /**
+      Initialize the mceCtx_t \c ctx.
+    */
+    pbool_t mceCtxInit(mceCtx_t *ctx);
+
+    /**
+      Cleanup, i.e. release all resourced from the mceCtx_t \c ctx.
+    */
+    pbool_t mceCtxCleanup(mceCtx_t *ctx);
+
+    /**
+      Register the namespace \ns in \c ctx.
+    */
+    pbool_t mceCtxUnderstandsNamespace(mceCtx_t *ctx, const xmlChar *ns);
+
+    /**
+     Register the namespace \ns in \c ctx.
+     */
+    pbool_t mceCtxSuspendProcessing(mceCtx_t *ctx, const xmlChar *ns, const xmlChar *ln);
+    
+
+
+#if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
+    /**
+    Subsume namespace \c ns_new with \c ns_old.
+     */
+    pbool_t mceCtxSubsumeNamespace(mceCtx_t *ctx, const xmlChar *prefix_new, const xmlChar *ns_new, const xmlChar *ns_old);
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* MCE_HELPER_H */

+ 422 - 0
mce/textreader.c

@@ -0,0 +1,422 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <mce/textreader.h>
+
+
+int mceTextReaderInit(mceTextReader_t *mceTextReader, xmlTextReaderPtr reader) {
+    memset(mceTextReader, 0, sizeof(*mceTextReader));
+    mceCtxInit(&mceTextReader->mceCtx);
+    mceTextReader->reader=reader;
+    return (NULL!=mceTextReader->reader?0:-1);
+}
+
+int mceTextReaderCleanup(mceTextReader_t *mceTextReader) {
+    mceCtxCleanup(&mceTextReader->mceCtx);
+    xmlTextReaderClose(mceTextReader->reader);
+    xmlFreeTextReader(mceTextReader->reader);
+    return 0;
+}
+
+static xmlChar *xmlStrDupArray(const xmlChar *value) {
+    opc_uint32_t len=xmlStrlen(value);
+    xmlChar *ret=(xmlChar *)xmlMalloc((2+len)*sizeof(xmlChar));
+    opc_uint32_t j=0;
+    for(opc_uint32_t i=0;i<len;i++) {
+        while(i<len && (value[i]==' ' || value[i]=='\t' || value[i]=='\r' || value[i]=='\n')) i++; // skip preceeding spaces
+        while(i<len && value[i]!=' ' && value[i]!='\t' && value[i]!='\r' && value[i]!='\n') ret[j++]=value[i++];
+        ret[j++]=0;
+    }
+    ret[j]=0;
+    return ret;
+}
+
+static xmlChar *xmlStrArrayFirst(xmlChar *a, int *entry_len) {
+    PASSERT(NULL!=entry_len);
+    *entry_len=xmlStrlen(a);
+    return a;
+}
+
+static pbool_t xmlStrArrayValid(const xmlChar *e) {
+    return NULL!=e && *e!=0;
+}
+
+static xmlChar *xmlStrArrayNext(xmlChar *e, int *entry_len) {
+    PASSERT(NULL!=entry_len);
+    PASSERT(xmlStrArrayValid(e));
+    xmlChar *ret=e+1+*entry_len;
+    *entry_len=xmlStrlen(ret);
+    return ret;
+}
+
+void mceRaiseError(xmlTextReader *reader, mceCtx_t *ctx, mceError_t error, const xmlChar *str, ...) {
+    va_list args;
+    va_start(args, str);
+    PASSERT(MCE_ERROR_NONE==ctx->error); // called twice? why?
+    ctx->error=error;
+    xmlChar buf[1024];
+    xmlStrVPrintf(buf, sizeof(buf), str, args);
+    xmlTextReaderErrorFunc f=NULL;
+    void *arg=NULL;
+    xmlTextReaderGetErrorHandler(reader, &f, &arg);    
+    if (NULL!=f) {
+        f(arg, (const char *)buf, XML_PARSER_SEVERITY_ERROR, (xmlTextReaderLocatorPtr)reader);
+    } else {
+        xmlGenericError(xmlGenericErrorContext, "%s!\n", (const char *)buf);
+    }
+    va_end(args);
+}
+
+
+static char ns_mce[]="http://schemas.openxmlformats.org/markup-compatibility/2006";
+static const char ns_xml[]="http://www.w3.org/2000/xmlns/";
+static const char _xmlns[]="xmlns";
+
+static void mceTextReaderProcessAttributes(xmlTextReader *reader, mceCtx_t *ctx, puint32_t level) {
+    xmlNodePtr c=xmlTextReaderCurrentNode(reader);
+    if (NULL!=c) { // make sure to inherit any namespace declaration on a parent MCE element
+        for(xmlNodePtr n=c->parent;
+            NULL!=n && XML_ELEMENT_NODE==n->type 
+            && NULL!=n->ns && 0==xmlStrcmp(n->ns->href, _X(ns_mce)) 
+            && NULL!=n->name
+            && (0==xmlStrcmp(_X("AlternateContent"), n->name) 
+                || 0==xmlStrcmp(_X("Choice"), n->name)  
+                || 0==xmlStrcmp(_X("Fallback"), n->name));
+            n=n->parent) {
+            for(xmlNs *nsDef=n->nsDef;NULL!=nsDef;nsDef=nsDef->next) {
+                xmlAttrPtr a=xmlHasNsProp(c, nsDef->prefix, _X(ns_xml));
+                if (NULL==a) { // only add a namespace if the prefix is not overwritten in the current node                    
+                    xmlNsPtr xmlns_ns=xmlNewNs(c, nsDef->href, nsDef->prefix);
+                }
+            }
+        }
+    }
+    if (1==xmlTextReaderHasAttributes(reader)) {
+        if (1==xmlTextReaderMoveToFirstAttribute(reader)) {
+            do {
+                if (0==xmlStrcmp(_X("Ignorable"), xmlTextReaderConstLocalName(reader)) &&
+                    0==xmlStrcmp(_X(ns_mce), xmlTextReaderConstNamespaceUri(reader))) {
+                        xmlChar *v=xmlStrDupArray(xmlTextReaderConstValue(reader));
+                        int prefix_len=0;
+                        for(xmlChar *prefix=xmlStrArrayFirst(v, &prefix_len);xmlStrArrayValid(prefix);prefix=xmlStrArrayNext(prefix, &prefix_len)) {
+                            xmlChar *ns_=xmlTextReaderLookupNamespace(reader, prefix);
+                            if (NULL!=ns_ && NULL==mceQNameLevelLookup(&ctx->understands_set, ns_, NULL, PFALSE)) {
+                                PENSURE(mceQNameLevelAdd(&ctx->ignorable_set, ns_, NULL, level));
+                            }
+                            xmlFree(ns_);
+                        }
+                        xmlFree(v);
+                } else if (0==xmlStrcmp(_X("ProcessContent"), xmlTextReaderConstLocalName(reader)) &&
+                           0==xmlStrcmp(_X(ns_mce), xmlTextReaderConstNamespaceUri(reader))) {
+                        xmlChar *v=xmlStrDupArray(xmlTextReaderConstValue(reader));
+                        int qname_len=0;
+                        for(xmlChar *qname=xmlStrArrayFirst(v, &qname_len);xmlStrArrayValid(qname);qname=xmlStrArrayNext(qname, &qname_len)) {
+                            int prefix=0; while(qname[prefix]!=':' && qname[prefix]!=0) prefix++;
+                            OPC_ASSERT(prefix<=qname_len);
+                            int ln=(prefix<qname_len?prefix+1:0);
+                            if (prefix<qname_len) {
+                                qname[prefix]=0;
+                                prefix=0;
+                            };
+                            xmlChar *ns_=xmlTextReaderLookupNamespace(reader, qname+prefix);
+                            if (NULL!=ns_ && NULL==mceQNameLevelLookup(&ctx->understands_set, ns_, NULL, PFALSE)) {
+                                PENSURE(mceQNameLevelAdd(&ctx->processcontent_set, ns_, xmlStrdup(qname+ln), level));
+
+                            }
+                        }
+                        xmlFree(v);
+                } else if (0==xmlStrcmp(_X("MustUnderstand"), xmlTextReaderConstLocalName(reader)) &&
+                           0==xmlStrcmp(_X(ns_mce), xmlTextReaderConstNamespaceUri(reader))) {
+                        xmlChar *v=xmlStrDupArray(xmlTextReaderConstValue(reader));
+                        int prefix_len=0;
+                        for(xmlChar *prefix=xmlStrArrayFirst(v, &prefix_len);xmlStrArrayValid(prefix);prefix=xmlStrArrayNext(prefix, &prefix_len)) {
+                            xmlChar *ns_=xmlTextReaderLookupNamespace(reader, prefix);
+                            if (NULL!=ns_ && NULL==mceQNameLevelLookup(&ctx->understands_set, ns_, NULL, PFALSE)) {
+                                mceRaiseError(reader, ctx, MCE_ERROR_MUST_UNDERSTAND, _X("MustUnderstand namespace \"%s\""), ns_);
+                            }
+                        }
+                        xmlFree(v);
+#if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
+                } else if (0==xmlStrcmp(_X(ns_xml), xmlTextReaderConstNamespaceUri(reader))) {
+                    mceQNameLevel_t *qnl=mceQNameLevelLookup(&ctx->subsume_prefix_set, xmlTextReaderConstValue(reader), NULL, PTRUE);
+                    if (NULL!=qnl) {
+                        const xmlChar *prefix=xmlTextReaderConstLocalName(reader);
+                        if (0!=xmlStrcmp(prefix, qnl->ln)) {
+                            // different binding!
+                            printf("prefix=%s\n", prefix);
+                            PASSERT(0); //@TODO add store prefix for subsumption namespaces...
+                        }
+                    }
+                } else {
+                    const xmlChar *ns_orig=xmlTextReaderConstNamespaceUri(reader);
+                    const xmlChar *ns=mceTextReaderSubsumeNS(ctx, ns_orig, xmlTextReaderConstLocalName(reader));
+                    if (ns_orig!=ns) {
+                        // namespace needs to be subsumed...
+                    }
+#endif
+                }
+            } while (1==xmlTextReaderMoveToNextAttribute(reader));
+        }
+        xmlAttrPtr remove=NULL;
+        if (1==xmlTextReaderMoveToFirstAttribute(reader)) {
+            do {
+                if (NULL!=remove) {
+                    xmlRemoveProp(remove); remove=NULL;
+                }
+                if (0==xmlStrcmp(_X(ns_mce), xmlTextReaderConstNamespaceUri(reader))) {
+                    OPC_ASSERT(XML_ATTRIBUTE_NODE==xmlTextReaderCurrentNode(reader)->type);
+                    remove=(xmlAttrPtr)xmlTextReaderCurrentNode(reader);
+                } else if (NULL!=mceQNameLevelLookup(&ctx->ignorable_set,
+                    xmlTextReaderConstNamespaceUri(reader), 
+                    NULL, 
+                    PFALSE)) {
+                        OPC_ASSERT(XML_ATTRIBUTE_NODE==xmlTextReaderCurrentNode(reader)->type);
+                        remove=(xmlAttrPtr)xmlTextReaderCurrentNode(reader);
+                }
+            } while (1==xmlTextReaderMoveToNextAttribute(reader));
+            OPC_ENSURE(1==xmlTextReaderMoveToElement(reader));
+            if (NULL!=remove) {
+                xmlRemoveProp(remove); remove=NULL;
+            }
+            OPC_ASSERT(NULL==remove);
+
+        }
+    }
+}
+
+static pbool_t mceTextReaderProcessStartElement(xmlTextReader *reader, mceCtx_t *ctx, puint32_t level, const xmlChar *ns, const xmlChar *ln) {
+    if (!mceSkipStackSkip(&ctx->skip_stack, level)) {
+        mceTextReaderProcessAttributes(reader, ctx, level);
+        if (0==xmlStrcmp(_X(ns_mce), ns) && 0==xmlStrcmp(_X("AlternateContent"), ln)) {
+            mceSkipStackPush(&ctx->skip_stack, level, level+1, MCE_SKIP_STATE_ALTERNATE_CONTENT);
+        } else if (0==xmlStrcmp(_X(ns_mce), ns) && 0==xmlStrcmp(_X("Choice"), ln)) {
+            xmlChar *req_ns=NULL;
+            if (1==xmlTextReaderMoveToAttribute(reader, _X("Requires"))) {
+                req_ns=xmlTextReaderLookupNamespace(reader, xmlTextReaderConstValue(reader));
+                OPC_ENSURE(1==xmlTextReaderMoveToElement(reader));
+            } else if (1==xmlTextReaderMoveToAttributeNs(reader, _X("Requires"), _X(ns_mce))) {
+                req_ns=xmlTextReaderLookupNamespace(reader, xmlTextReaderConstValue(reader));
+                OPC_ENSURE(1==xmlTextReaderMoveToElement(reader));
+            }
+            if (NULL==req_ns) {
+                mceRaiseError(reader, ctx, MCE_ERROR_XML, _X("Missing \"Requires\" attribute"));
+            } else if (NULL==mceSkipStackTop(&ctx->skip_stack)
+                   || !(mceSkipStackTop(&ctx->skip_stack)->state==MCE_SKIP_STATE_ALTERNATE_CONTENT || mceSkipStackTop(&ctx->skip_stack)->state==MCE_SKIP_STATE_CHOICE_MATCHED)
+                   || mceSkipStackTop(&ctx->skip_stack)->level_start+1!=level
+                   || mceSkipStackTop(&ctx->skip_stack)->level_end!=level) {
+                mceRaiseError(reader, ctx, MCE_ERROR_XML, _X("Choice element does not appear at a valid position."));
+            } else if (mceQNameLevelLookup(&ctx->understands_set, req_ns, NULL, PFALSE) && mceSkipStackTop(&ctx->skip_stack)->state!=MCE_SKIP_STATE_CHOICE_MATCHED) {
+                mceSkipStackTop(&ctx->skip_stack)->state=MCE_SKIP_STATE_CHOICE_MATCHED;
+                mceSkipStackPush(&ctx->skip_stack, level, level+1, MCE_SKIP_STATE_IGNORE);
+            } else {
+                mceSkipStackPush(&ctx->skip_stack, level, PUINT32_MAX, MCE_SKIP_STATE_IGNORE);
+            }
+            if (NULL!=req_ns) xmlFree(req_ns);
+        } else if (0==xmlStrcmp(_X(ns_mce), ns) && 0==xmlStrcmp(_X("Fallback"), ln)) {
+            if (NULL==mceSkipStackTop(&ctx->skip_stack) 
+                || !(mceSkipStackTop(&ctx->skip_stack)->state==MCE_SKIP_STATE_ALTERNATE_CONTENT || mceSkipStackTop(&ctx->skip_stack)->state==MCE_SKIP_STATE_CHOICE_MATCHED)
+                || mceSkipStackTop(&ctx->skip_stack)->level_start+1!=level
+                || mceSkipStackTop(&ctx->skip_stack)->level_end!=level) {
+                mceRaiseError(reader, ctx, MCE_ERROR_XML, _X("Fallback element does not appear at a valid position."));
+            } else if (mceSkipStackTop(&ctx->skip_stack)->state!=MCE_SKIP_STATE_CHOICE_MATCHED) {
+                mceSkipStackPush(&ctx->skip_stack, level, level+1, MCE_SKIP_STATE_IGNORE);
+            } else {
+                mceSkipStackPush(&ctx->skip_stack, level, PUINT32_MAX, MCE_SKIP_STATE_IGNORE);
+            }
+        } else if (mceQNameLevelLookup(&ctx->ignorable_set, ns, NULL, PFALSE)
+            && !mceQNameLevelLookup(&ctx->understands_set, ns, NULL, PFALSE)) {
+                if (mceQNameLevelLookup(&ctx->processcontent_set, ns, ln, PFALSE)) {
+                    mceSkipStackPush(&ctx->skip_stack, level, level+1, MCE_SKIP_STATE_IGNORE);
+                } else {
+                    mceSkipStackPush(&ctx->skip_stack, level, PUINT32_MAX, MCE_SKIP_STATE_IGNORE);
+                }
+        }
+    }
+    return mceSkipStackSkip(&ctx->skip_stack, level);
+}
+
+static pbool_t mceTextReaderProcessEndElement(xmlTextReader *reader, mceCtx_t *ctx, puint32_t level, const xmlChar *ns, const xmlChar *ln) {
+    pbool_t skiped=PFALSE;
+    if (mceSkipStackSkip(&ctx->skip_stack, level)) {
+        if (mceSkipStackTop(&ctx->skip_stack)->level_start==level) {
+            mceSkipStackPop(&ctx->skip_stack);
+        } else if (mceSkipStackTop(&ctx->skip_stack)->level_end==level) {
+            mceSkipStackTop(&ctx->skip_stack)->level_end--;
+            PASSERT(mceSkipStackTop(&ctx->skip_stack)->level_start<mceSkipStackTop(&ctx->skip_stack)->level_end);
+        }
+        skiped=PTRUE;
+    }
+    mceQNameLevelCleanup(&ctx->ignorable_set, level);
+    mceQNameLevelCleanup(&ctx->processcontent_set, level);
+    mceQNameLevelCleanup(&ctx->understands_set, level);
+    mceQNameLevelCleanup(&ctx->suspended_set, level); 
+    return skiped;
+}
+
+int mceTextReaderPostprocess(xmlTextReader *reader, mceCtx_t *ctx, int ret) {
+    pbool_t suspend=ctx->mce_disabled;
+    const xmlChar *ns=NULL;
+    const xmlChar *ln=NULL;
+    if (MCE_ERROR_NONE!=ctx->error) {
+        ret=-1;
+    } else {
+        ns=xmlTextReaderConstNamespaceUri(reader);
+        ln=xmlTextReaderConstLocalName(reader);
+        if (XML_READER_TYPE_ELEMENT==xmlTextReaderNodeType(reader)) {
+            if (ctx->suspended_level>0 || NULL!=mceQNameLevelLookup(&ctx->suspended_set, ns, ln, PFALSE)) {
+                suspend=PTRUE;
+                if (!xmlTextReaderIsEmptyElement(reader)) {
+                    ctx->suspended_level++;
+                }
+            }
+        } else if (ctx->suspended_level>0) {
+            suspend=PTRUE;
+            if (XML_READER_TYPE_END_ELEMENT==xmlTextReaderNodeType(reader)) {
+                ctx->suspended_level--;
+            }
+        }
+    }
+    pbool_t skip=!suspend;
+    while(1==ret && skip) {
+        if (XML_READER_TYPE_ELEMENT==xmlTextReaderNodeType(reader)) {
+            skip=mceTextReaderProcessStartElement(reader, ctx, xmlTextReaderDepth(reader), ns, ln);
+            if (xmlTextReaderIsEmptyElement(reader)) {
+                PENSURE(mceTextReaderProcessEndElement(reader, ctx, xmlTextReaderDepth(reader), ns, ln)==skip);
+            }
+        } else if (XML_READER_TYPE_END_ELEMENT==xmlTextReaderNodeType(reader)) {
+            skip=mceTextReaderProcessEndElement(reader, ctx, xmlTextReaderDepth(reader), ns, ln);
+        } else {
+            skip=mceSkipStackSkip(&ctx->skip_stack, xmlTextReaderDepth(reader));
+        }
+        if (skip) {
+            if (-1!=(ret=xmlTextReaderRead(reader))) { // skip element
+                ns=xmlTextReaderConstNamespaceUri(reader); // get next ns
+                ln=xmlTextReaderConstLocalName(reader);  // get net local name
+            }
+        }
+        if (MCE_ERROR_NONE!=ctx->error) {
+            ret=-1;
+        }
+    }
+    if (-1==ret && MCE_ERROR_NONE==ctx->error) {
+        ctx->error=MCE_ERROR_XML; //@TODO be more specific about the type of libxml2 error.
+    }
+    return ret;
+}
+
+
+mceError_t mceTextReaderGetError(mceTextReader_t *mceTextReader) {
+    return mceTextReader->mceCtx.error;
+}
+
+int mceTextReaderRead(mceTextReader_t *mceTextReader) {
+    return mceTextReaderPostprocess(mceTextReader->reader, &mceTextReader->mceCtx, xmlTextReaderRead(mceTextReader->reader));
+}
+
+int mceTextReaderNext(mceTextReader_t *mceTextReader) {
+    return mceTextReaderPostprocess(mceTextReader->reader, &mceTextReader->mceCtx, xmlTextReaderNext(mceTextReader->reader));
+}
+
+
+int mceTextReaderDump(mceTextReader_t *mceTextReader, xmlTextWriter *writer, pbool_t fragment) {
+    int ret=-1;
+    if (XML_READER_TYPE_ELEMENT==xmlTextReaderNodeType(mceTextReader->reader)) {
+        const xmlChar *ns=xmlTextReaderConstNamespaceUri(mceTextReader->reader);
+        const xmlChar *ln=xmlTextReaderConstLocalName(mceTextReader->reader);
+        if (NULL!=ns) {
+            xmlTextWriterStartElementNS(writer, xmlTextReaderConstPrefix(mceTextReader->reader), ln, NULL);
+        } else {
+            xmlTextWriterStartElement(writer, ln);
+        }
+        if (xmlTextReaderHasAttributes(mceTextReader->reader)) {
+            if (1==xmlTextReaderMoveToFirstAttribute(mceTextReader->reader)) {
+                do {
+                    const xmlChar *attr_ns=xmlTextReaderConstNamespaceUri(mceTextReader->reader);
+                    const xmlChar *attr_ln=xmlTextReaderConstLocalName(mceTextReader->reader);
+                    const xmlChar *attr_val=xmlTextReaderConstValue(mceTextReader->reader);
+                    if (NULL!=attr_ns && 0==xmlStrcmp(attr_ns, _X(ns_xml))) {
+                        if (0==xmlStrcmp(attr_ln, _X(_xmlns))) {
+                            xmlTextWriterWriteAttribute(writer, attr_ln, attr_val);
+                        } else {
+                            xmlTextWriterWriteAttributeNS(writer, _X(_xmlns), attr_ln, NULL, attr_val);
+                        }
+                    } else {
+                        if (NULL!=ns) {
+                            xmlTextWriterWriteAttributeNS(writer, xmlTextReaderConstPrefix(mceTextReader->reader), attr_ln, NULL, attr_val);
+                        } else {
+                            xmlTextWriterWriteAttribute(writer, attr_ln, attr_val);
+                        }
+                    }
+                } while (1==xmlTextReaderMoveToNextAttribute(mceTextReader->reader));
+            }
+            PENSURE(1==xmlTextReaderMoveToElement(mceTextReader->reader));
+        }
+        if (!xmlTextReaderIsEmptyElement(mceTextReader->reader)) {
+            ret=mceTextReaderRead(mceTextReader); // read start element
+            while (1==ret && XML_READER_TYPE_END_ELEMENT!=xmlTextReaderNodeType(mceTextReader->reader)) {
+                ret=mceTextReaderDump(mceTextReader, writer, fragment);
+            }
+            PASSERT(-1==ret || XML_READER_TYPE_END_ELEMENT==xmlTextReaderNodeType(mceTextReader->reader));
+            ret=mceTextReaderRead(mceTextReader); // read end element
+        } else {
+            ret=mceTextReaderRead(mceTextReader); // read empty element
+        }
+        xmlTextWriterEndElement(writer);
+    } else if (XML_READER_TYPE_TEXT==xmlTextReaderNodeType(mceTextReader->reader)) {
+        xmlTextWriterWriteString(writer, xmlTextReaderConstValue(mceTextReader->reader));
+        ret=mceTextReaderRead(mceTextReader); // read end element
+    } else if (XML_READER_TYPE_SIGNIFICANT_WHITESPACE==xmlTextReaderNodeType(mceTextReader->reader)) {
+        xmlTextWriterWriteString(writer, xmlTextReaderConstValue(mceTextReader->reader));
+        ret=mceTextReaderRead(mceTextReader); // read end element
+    } else if (XML_READER_TYPE_NONE==xmlTextReaderNodeType(mceTextReader->reader)) {
+        ret=mceTextReaderRead(mceTextReader);
+        if (1==ret && XML_READER_TYPE_NONE!=xmlTextReaderNodeType(mceTextReader->reader)) {
+            if (!fragment) xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
+            ret=mceTextReaderDump(mceTextReader, writer, fragment);
+            if (!fragment) xmlTextWriterEndDocument(writer);
+        }
+    } else {
+        if (1==(ret=mceTextReaderNext(mceTextReader))) { // skip element
+            ret=mceTextReaderDump(mceTextReader, writer, fragment);
+        }
+    }
+    return ret;
+}
+
+int mceTextReaderUnderstandsNamespace(mceTextReader_t *mceTextReader, const xmlChar *ns) {
+    return (mceCtxUnderstandsNamespace(&mceTextReader->mceCtx, ns)?0:-1);
+}
+
+pbool_t mceTextReaderDisableMCE(mceTextReader_t *mceTextReader, pbool_t flag) {
+    pbool_t ret=mceTextReader->mceCtx.mce_disabled>0;
+    mceTextReader->mceCtx.mce_disabled=flag;
+    return ret;
+}

+ 464 - 0
mce/textreader.h

@@ -0,0 +1,464 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file mce/textreader.h
+ 
+ */
+#ifndef MCE_TEXTREADER_H
+#define MCE_TEXTREADER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    /**
+      A handle to an MCE-aware libxml2 xmlTextReader.
+    */
+    typedef struct MCE_TEXTREADER mceTextReader_t;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+
+#include <mce/config.h>
+#include <opc/opc.h>
+#include <mce/helper.h>
+#include <libxml/xmlwriter.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    struct MCE_TEXTREADER {
+        xmlTextReaderPtr reader;
+        mceCtx_t mceCtx;
+    };
+
+    /**
+      Wrapper around an libxml2 xmlTextReaderRead function.
+      \see http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderRead
+    */
+    int mceTextReaderRead(mceTextReader_t *mceTextReader);
+
+    /**
+      Wrapper around a libxml2 xmlTextReaderNext function.
+      \see http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderNext
+    */
+    int mceTextReaderNext(mceTextReader_t *mceTextReader);
+
+    /** 
+      Creates an mceTextReader from an XmlTextReader. 
+      \code
+      mceTextReader reader;
+      mceTextReaderInit(&reader, xmlNewTextReaderFilename("sample.xml"));
+      // reader is ready to use.
+      mceTextReaderCleanup(&reader);
+      \endcode
+      \see http://xmlsoft.org/html/libxml-xmlreader.html#xmlNewTextReaderFilename
+    */
+    int mceTextReaderInit(mceTextReader_t *mceTextReader, xmlTextReaderPtr reader);
+
+    /**
+      Cleanup MCE reader, i.e. free all resources. Also calls xmlTextReaderClose and xmlFreeTextReader.
+      \see http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderClose
+      \see http://xmlsoft.org/html/libxml-xmlreader.html#xmlFreeTextReader
+    */
+    int mceTextReaderCleanup(mceTextReader_t *mceTextReader);
+
+    /** 
+      Reads all events \c mceTextReader and pipes them to \writer.
+      \code
+      mceTextReader reader;
+      mceTextReaderInit(&reader, xmlNewTextReaderFilename("sample.xml"));
+      mceTextReaderUnderstandsNamespace(&reader, _X("http://myextension"));
+      xmlTextWriterPtr writer=xmlNewTextWriterFilename("out.xml", 0);
+      mceTextReaderDump(&reader, writer, P_FALSE);
+      xmlFreeTextWriter(writer);
+      mceTextReaderCleanup(&reader);
+      \endcode
+      */
+    int mceTextReaderDump(mceTextReader_t *mceTextReader, xmlTextWriter *writer, pbool_t fragment);
+
+    /**
+      Registers an MCE namespace.
+      \see mceTextReaderDump()
+      */
+    int mceTextReaderUnderstandsNamespace(mceTextReader_t *mceTextReader, const xmlChar *ns);
+
+    /**
+     Disable MCE processing.
+     \return Returns old value.
+     */
+    pbool_t mceTextReaderDisableMCE(mceTextReader_t *mceTextReader, pbool_t flag);
+
+
+    /**
+     Signal an error to the MCE processor.
+     */
+    void mceRaiseError(xmlTextReader *reader, mceCtx_t *ctx, mceError_t error, const xmlChar *str, ...);
+
+    /**
+        Internal function which does the MCE postprocessing. E.g. mceTextReaderRead() is implemented as
+        \code
+        mceTextReaderPostprocess(mceTextReader->reader, &mceTextReader->mceCtx, xmlTextReaderRead(mceTextReader->reader))
+        \endcode
+        This function is exposed to make existing libxm2 xmlTextReader MCE aware.
+    */
+    int mceTextReaderPostprocess(xmlTextReader *reader, mceCtx_t *ctx, int ret);
+
+    /**
+     Get the error code.
+     */
+    mceError_t mceTextReaderGetError(mceTextReader_t *mceTextReader);
+
+/**
+ Helper macro to declare a start/end document block in a declarative way:
+ \code
+  mce_start_document(reader) {
+  } mce_end_document(reader);
+  \endcode
+  \hideinitializer
+*/
+#define mce_start_document(_reader_) \
+    if (NULL!=(_reader_)) {            \
+        mceTextReaderRead(_reader_); \
+        if (0)                     
+
+/**
+  \see mce_start_document.
+  \hideinitializer
+*/
+#define mce_end_document(_reader_)   \
+    } /* if (NULL!=reader) */        \
+
+
+/**
+  Container for mce_start_element and mce_start_attribute declarations.
+  \see mce_match_element
+  \see mce_match_attribute
+  \hideinitializer
+  */
+#define mce_start_choice(_reader_)  \
+    if (0)                          
+
+/**
+  \see mce_start_choice
+  \hideinitializer
+  */
+#define mce_end_choice(_reader_) 
+
+
+/**
+  Skips the attributes. 
+  \see mce_match_element.
+  \hideinitializer
+*/
+#define mce_skip_attributes(_reader_) \
+    mce_start_attributes(_reader_) {  \
+    } mce_end_attributes(_reader_);   
+
+
+/**
+  Skips the attributes. 
+  \see mce_match_attribute.
+  \hideinitializer
+*/
+#define mce_skip_children(_reader_) \
+    mce_start_children(_reader_) {  \
+    } mce_end_children(_reader_);   
+
+/**
+  \see mce_start_element.
+  \hideinitializer
+*/
+#define mce_start_children(_reader_)                  \
+if (!xmlTextReaderIsEmptyElement((_reader_)->reader)) { \
+    mceTextReaderRead(_reader_); do {                 \
+        if (0)                                        
+
+/**
+  \see mce_start_element.
+  \hideinitializer
+*/
+#define mce_end_children(_reader_)                                                      \
+        else {                                                                          \
+            if (XML_READER_TYPE_END_ELEMENT!=xmlTextReaderNodeType((_reader_)->reader)) { \
+                mceTextReaderNext(_reader_); /*skip unhandled element */                \
+            }                                                                           \
+        }                                                                               \
+    } while(XML_READER_TYPE_END_ELEMENT!=xmlTextReaderNodeType((_reader_)->reader) &&     \
+            XML_READER_TYPE_NONE!=xmlTextReaderNodeType((_reader_)->reader));             \
+} /* if (!xmlTextReaderIsEmptyElement(reader->reader)) */                               
+
+
+/**
+  Helper macro to match an element. Usefull for calling code in a seperate function:
+
+  \code
+  void handleElement(reader) {
+    mce_start_choice(reader) {
+        mce_start_element(reader, _X("ns"), _X("element")) {
+            
+        } mce_end_element(reader)
+    } mce_end_choice(reader);
+  }
+
+  void parse(reader) {
+    mce_start_document(reader) {
+      mce_start_element(reader, _X("ns"), _X("ln")) {
+        mce_skip_attributes(reader);
+        mce_start_children(reader) {
+           mce_match_element(reader, _X("ns"), _X("element")) {
+             handleElement(reader);
+           }
+        } mce_end_children(reader);
+      } mce_end_element();
+    } mce_end_document(reader);
+  }
+  \endcode
+  \hideinitializer
+*/
+#define mce_match_element(_reader_, ns, ln)                                                       \
+    } else if (XML_READER_TYPE_ELEMENT==xmlTextReaderNodeType((_reader_)->reader)                 \
+            && (NULL==ns || 0==xmlStrcmp(ns, xmlTextReaderConstNamespaceUri((_reader_)->reader))) \
+            && (NULL==ln || 0==xmlStrcmp(ln, xmlTextReaderConstLocalName((_reader_)->reader)))) { 
+
+
+/**
+ Helper macro to declare a element block in a declarative way:
+ \code
+  mce_start_element(reader) {
+    mce_start_attributes(reader) {
+      mce_start_attribute(reader, _X("ns"), _X("lnA")) {
+         // code for handling lnA.
+      } mce_end_attribute(reader);
+      mce_start_attribute(reader, _X("ns"), _X("lnB")) {
+         // code for handling lnB.
+      } mce_end_attribute(reader);
+    } mce_end_attributes(reader);
+    mce_start_children(reader) {
+        mce_start_element(reader, _X("ns"), _X("lnA")) {
+         // code for handling lnA.
+        } mce_end_element(reader);
+        mce_start_element(reader, _X("ns"), _X("lnB")) {
+         // code for handling lnB.
+        } mce_end_element(reader);
+        mce_start_text(reader) {
+         // code for handling text.
+        } mce_end_text(reader);
+    } mce_end_children(reader);
+  } mce_end_element(reader);
+  \endcode
+  \hideinitializer
+*/
+#define mce_start_element(_reader_, ns, ln) \
+    mce_match_element(_reader_, ns, ln)     
+
+/**
+  \see mce_start_element.
+  \hideinitializer
+*/
+#define mce_end_element(_reader_) \
+    mceTextReaderNext(_reader_)   
+
+/**
+  Matches #TEXT without consuming it.
+  \hideinitializer
+*/
+#define mce_match_text(_reader_)                                                                   \
+    } else if (XML_READER_TYPE_TEXT==xmlTextReaderNodeType((_reader_)->reader)                     \
+            || XML_READER_TYPE_SIGNIFICANT_WHITESPACE==xmlTextReaderNodeType((_reader_)->reader)) {
+
+
+/**
+  \see mce_start_element.
+  \hideinitializer
+*/
+#define mce_start_text(_reader_) \
+    mce_match_text(_reader_)      
+
+/**
+  \see mce_start_element.
+  \hideinitializer
+*/
+#define mce_end_text(_reader_) \
+    mceTextReaderNext(_reader_)
+
+/**
+  \see mce_start_element.
+  \hideinitializer
+*/
+#define mce_start_attributes(_reader_)                            \
+    if (1==xmlTextReaderMoveToFirstAttribute((_reader_)->reader)) { \
+        do {                                                      \
+            if (0)                                                
+
+/**
+  \see mce_start_element.
+  \hideinitializer
+*/
+#define mce_end_attributes(_reader_)                                    \
+            else { /* skipped attribute */ }                            \
+        } while(1==xmlTextReaderMoveToNextAttribute((_reader_)->reader)); \
+    xmlTextReaderMoveToElement((_reader_)->reader); }                     
+
+/**
+  Helper macro to match an attribute. Usefull for calling code in a seperate function:
+
+  \code
+  void handleA(reader) {
+    mce_start_choice(reader) {
+        mce_start_attribute(reader, _X("ns"), _X("attr")) {
+
+        } mce_end_attribute(reader);
+    } mce_end_choice(reader);
+  }
+
+  void parse(reader) {
+    mce_start_document(reader) {
+      mce_start_element(reader, _X("ns"), _X("ln")) {
+        mce_start_attributes(reader) {
+           mce_match_attribute(reader, _X("ns"), _X("attr")) {
+             handleA(reader);
+           }
+        } mce_end_attributes(reader);
+        mce_skip_children(reader);
+      } mce_end_element();
+    } mce_end_document(reader);
+  }
+  \endcode
+  \hideinitializer
+*/
+#define mce_match_attribute(_reader_, ns, ln)                                                   \
+    } else if ((NULL==ns || 0==xmlStrcmp(ns, xmlTextReaderConstNamespaceUri((_reader_)->reader))) \
+            && (NULL==ln || 0==xmlStrcmp(ln, xmlTextReaderConstLocalName((_reader_)->reader)))) { 
+
+/**
+  \see mce_start_element.
+  \hideinitializer
+*/
+#define mce_start_attribute(_reader_, ns, ln) \
+    mce_match_attribute(_reader_, ns, ln) 
+
+/**
+  \see mce_start_element.
+  \hideinitializer
+*/
+#define mce_end_attribute(_reader_)
+
+
+/**
+  Error handling for MCE parsers.
+  \code
+   mce_start_element(&reader, NULL, _X("Default")) {
+       const xmlChar *ext=NULL;
+       const xmlChar *type=NULL;
+       mce_start_attributes(&reader) {
+           mce_start_attribute(&reader, NULL, _X("Extension")) {
+               ext=xmlTextReaderConstValue(reader.reader);
+           } mce_end_attribute(&reader);
+           mce_start_attribute(&reader, NULL, _X("ContentType")) {
+               type=xmlTextReaderConstValue(reader.reader);
+           } mce_end_attribute(&reader);
+       } mce_end_attributes(&reader);
+       mce_error_guard_start(&reader) {
+           mce_error(&reader, NULL==ext || ext[0]==0, MCE_ERROR_VALIDATION, "Missing @Extension attribute!");
+           mce_error(&reader, NULL==type || type[0]==0, MCE_ERROR_VALIDATION, "Missing @ContentType attribute!");
+           opcContainerType *ct=insertType(c, type, OPC_TRUE);
+           mce_error(&reader, NULL==ct, MCE_ERROR_MEMORY, NULL);
+           opcContainerExtension *ce=opcContainerInsertExtension(c, ext, OPC_TRUE);
+           mce_error(&reader, NULL==ce, MCE_ERROR_MEMORY, NULL);
+           mce_errorf(&reader, NULL!=ce->type && 0!=xmlStrcmp(ce->type, type), MCE_ERROR_VALIDATION, "Extension \"%s\" is mapped to type \"%s\" as well as \"%s\"", ext, type, ce->type);
+           ce->type=ct->type;
+       } mce_error_guard_end(&reader);
+       mce_skip_children(&reader);
+   } mce_end_element(&reader);
+  \endcode
+  \hideinitializer
+*/
+#define mce_error_guard_start(_reader_) if (MCE_ERROR_NONE==(_reader_)->mceCtx.error) do {
+
+/**
+  \see mce_error_guard_start
+  \hideinitializer
+*/
+#define mce_error_guard_end(_reader_)  } while(0)
+
+/**
+  Signal an error if guard if false.
+  \hideinitializer
+*/
+#define mce_error(_reader_, guard, err, msg) if (guard) { (_reader_)->mceCtx.error=(err); fprintf(stderr, (NULL!=msg?msg:#err));  continue; }
+
+/**
+  Signal an error if guard if false.
+  \hideinitializer
+*/
+#if defined(__GNUC__)
+#define mce_errorf(_reader_, guard, err, msg, ...) if (guard) { mceRaiseError((_reader_)->reader, &(_reader_)->mceCtx, err, _X((NULL!=msg?msg:#err)), ##__VA_ARGS__ );  continue; }
+#else
+#define mce_errorf(_reader_, guard, err, msg, ...) if (guard) { mceRaiseError((_reader_)->reader, &(_reader_)->mceCtx, err, _X((NULL!=msg?msg:#err)), __VA_ARGS__ );  continue; }
+#endif
+
+/**
+  Only issues the error when in "strict mode".
+  \hideinitializer
+*/
+#define mce_error_strict mce_error
+
+/**
+  \see mce_error_strict
+  \hideinitializer
+*/
+#define mce_error_strictf mce_errorf
+
+
+/**
+  Marker for a MCE defintion.
+  \hideinitializer
+*/
+#define mce_def
+
+/**
+  Marker for a MCE reference.
+  \hideinitializer
+*/
+#define mce_ref(r) (r)
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* MCE_TEXTREADER_H */

+ 297 - 0
mce/textwriter.c

@@ -0,0 +1,297 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <mce/textwriter.h>
+
+struct MCE_TEXTWRITER_STRUCT {
+    xmlTextWriterPtr writer;
+    puint32_t level;
+    mceQNameLevelSet_t registered_set;
+    mceQNameLevelSet_t processcontent_set;
+    const xmlChar *ns_mce;
+};
+
+
+mceTextWriter *mceTextWriterCreateIO(xmlOutputWriteCallback iowrite, xmlOutputCloseCallback  ioclose, void *ioctx, xmlCharEncodingHandlerPtr encoder) {
+    mceTextWriter *w=(mceTextWriter*)xmlMalloc(sizeof(mceTextWriter));
+    if (NULL!=w) {
+        memset(w, 0, sizeof(*w));
+        xmlOutputBufferPtr out=xmlOutputBufferCreateIO(iowrite, ioclose, ioctx, encoder);
+        w->writer=xmlNewTextWriter(out);
+        if (NULL==w->writer) {
+            // creation failed
+            xmlOutputBufferClose(out);
+            xmlFree(w);
+            w=NULL;
+        } else {
+            // creation OK
+            w->ns_mce=mceTextWriterRegisterNamespace(w, _X("http://schemas.openxmlformats.org/markup-compatibility/2006"), _X("mce"), 0);
+            mceTextWriterRegisterNamespace(w, _X("http://www.w3.org/XML/1998/namespace"), _X("xml"), 0);
+        }
+    }
+    return w;
+}
+
+int mceTextWriterFree(mceTextWriter *w) {
+    int ret=0;
+    if (NULL!=w) {
+        xmlFreeTextWriter(w->writer);
+        if (NULL!=w->registered_set.list_array) xmlFree(w->registered_set.list_array);
+        if (NULL!=w->processcontent_set.list_array) xmlFree(w->processcontent_set.list_array);
+        xmlFree(w);
+        ret=1;
+    }
+    return ret;
+}
+
+int mceTextWriterStartDocument(mceTextWriter *w) {
+    int ret=0;
+    ret=xmlTextWriterStartDocument(w->writer, NULL, NULL, NULL);
+    PASSERT(0==w->level);
+    return ret;
+}
+
+int mceTextWriterEndDocument(mceTextWriter *w) {
+    int ret=0;
+    PASSERT(0==w->level);
+    mceQNameLevelCleanup(&w->registered_set, w->level);
+    ret=xmlTextWriterEndDocument(w->writer);
+    return ret;
+}
+
+int mceTextWriterStartElement(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln) {
+    int ret=0;
+    PASSERT(w->level>=w->registered_set.max_level);
+    mceQNameLevel_t* qName=mceQNameLevelLookup(&w->registered_set, ns, NULL, PTRUE);
+    if (NULL!=qName) {
+        if (NULL==qName->ln) {
+            ret=xmlTextWriterStartElement(w->writer, ln);
+        } else {
+            ret=xmlTextWriterStartElementNS(w->writer, qName->ln, ln, (w->level==w->registered_set.max_level?ns:NULL));
+        }
+        if (w->level==w->registered_set.max_level) {
+            // register new namespaces
+            puint32_t ignorables=0;
+            for(puint32_t i=0;i<w->registered_set.list_items;i++) {
+                if (w->registered_set.list_array[i].level==w->level) {
+                    if ((w->registered_set.list_array[i].flag&MCE_IGNORABLE)==MCE_IGNORABLE) {
+                        ignorables++;
+                    }
+                    if (w->registered_set.list_array[i].ns!=qName->ns) {
+                        if (!(w->registered_set.list_array[i].ln[0]=='x' 
+                           && w->registered_set.list_array[i].ln[1]=='m' 
+                           && w->registered_set.list_array[i].ln[2]=='l' 
+                           && w->registered_set.list_array[i].ln[3]==0)) {
+                            xmlTextWriterWriteAttributeNS(w->writer, 
+                                                          _X("xmlns"), 
+                                                          w->registered_set.list_array[i].ln, 
+                                                          NULL, 
+                                                          w->registered_set.list_array[i].ns);
+                        }
+                    }
+                }
+            }
+            if (ignorables>0) {
+                mceQNameLevel_t* mceQName=mceQNameLevelLookup(&w->registered_set, w->ns_mce, NULL, PTRUE);
+                PASSERT(NULL!=mceQName);
+                if (NULL!=mceQName) {
+                    xmlTextWriterStartAttributeNS(w->writer,
+                                                  mceQName->ln,
+                                                  _X("Ignorable"),
+                                                  NULL);
+                    puint32_t j=0;
+                    for(puint32_t i=0;i<w->registered_set.list_items;i++) {
+                        if (w->registered_set.list_array[i].level==w->level && MCE_IGNORABLE==(w->registered_set.list_array[i].flag&MCE_IGNORABLE)) {
+                            xmlTextWriterWriteString(w->writer, w->registered_set.list_array[i].ln);
+                            if (++j<ignorables) {
+                                xmlTextWriterWriteString(w->writer, _X(" "));
+                            }
+                        }
+                    }
+                    PASSERT(j==ignorables);
+                    xmlTextWriterEndAttribute(w->writer);
+                }
+            }
+        }
+        if (w->level==w->processcontent_set.max_level) {
+            // write process content attribute
+            puint32_t v_len=0;
+            xmlChar *v=NULL;
+            for(puint32_t i=0;i<w->processcontent_set.list_items;i++) {
+                if (w->processcontent_set.list_array[i].level==w->level) {
+                    mceQNameLevel_t* qName=mceQNameLevelLookup(&w->registered_set, w->processcontent_set.list_array[i].ns, NULL, PTRUE);
+                    PASSERT(NULL!=qName); // namespace not registered?
+                    if (NULL!=qName) {
+                        puint32_t len=(v_len>0?xmlStrlen(_X(" ")):0)+xmlStrlen(qName->ln)+xmlStrlen(_X(":"))+xmlStrlen(w->processcontent_set.list_array[i].ln)+1;
+                        v=(xmlChar *)xmlRealloc(v, v_len+len);
+                        if (v_len>0) { v[v_len++]=' '; len--; }
+                        int l=xmlStrPrintf(v+v_len, len, _X("%s:%s"), qName->ln, w->processcontent_set.list_array[i].ln);
+                        PASSERT(1+l==len); // cause by terminating "0"
+                        v_len+=l;
+                    }
+                }
+            }
+            if (NULL!=v) {
+                mceQNameLevel_t* mceQName=mceQNameLevelLookup(&w->registered_set, w->ns_mce, NULL, PTRUE);
+                PASSERT(NULL!=mceQName);
+                if (NULL!=mceQName) {
+                    xmlTextWriterWriteAttributeNS(w->writer, mceQName->ln, _X("ProcessContent"), NULL, v);
+                }
+                xmlFree(v); v=NULL;
+            }
+        }
+    } else {
+        // namespace not registered => not good!
+        PASSERT(0==ret);
+    }
+    w->level++;
+    return ret;
+}
+
+int mceTextWriterEndElement(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln) {
+    int ret=0;
+    ret=xmlTextWriterEndElement(w->writer);
+    mceQNameLevelCleanup(&w->registered_set, w->level);
+    mceQNameLevelCleanup(&w->processcontent_set, w->level);
+    PASSERT(w->level>0);
+    w->level--;
+    return ret;
+}
+
+int mceTextWriterWriteString(mceTextWriter *w, const xmlChar *content) {
+    int ret=0;
+    ret=xmlTextWriterWriteString(w->writer, content);
+    return ret;
+}
+
+const xmlChar *mceTextWriterRegisterNamespace(mceTextWriter *w, const xmlChar *ns, const xmlChar *prefix, int flags) {
+    mceQNameLevelAdd(&w->registered_set, ns, prefix, w->level);
+    mceQNameLevel_t *ret=mceQNameLevelLookup(&w->registered_set, ns, prefix, PFALSE);
+    PASSERT(NULL!=ret); // not inserted? why?
+    if (NULL!=ret) {
+        ret->flag=flags;
+        return ret->ns;
+    } else {
+        return NULL;
+    }
+}
+
+int mceTextWriterProcessContent(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln) {
+    return mceQNameLevelAdd(&w->processcontent_set, ns, ln, w->level)?0:-1;
+}
+
+int mceTextWriterAttributeF(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln, const char *value, ...) {
+    va_list args;
+    int ret=0;
+    va_start(args, value); 
+    PASSERT(w->level>=w->registered_set.max_level);
+    mceQNameLevel_t* qName=mceQNameLevelLookup(&w->registered_set, ns, NULL, PTRUE);
+    if (NULL!=qName) {
+        if (NULL==qName->ln) {
+            ret=xmlTextWriterWriteVFormatAttribute(w->writer, ln, value, args);
+        } else {
+            ret=xmlTextWriterWriteVFormatAttributeNS(w->writer, qName->ln, ln, NULL, value, args);
+        }
+    } else {
+        PASSERT(0); // hmm namespace not registered?
+    }
+    va_end(args);
+    return ret;
+}
+
+int mceTextWriterStartAlternateContent(mceTextWriter *w) {
+    return xmlTextWriterStartElementNS(w->writer, _X("mce"), _X("AlternateContent"), NULL);
+}
+
+int mceTextWriterEndAlternateContent(mceTextWriter *w) {
+    return xmlTextWriterEndElement(w->writer);
+}
+
+int mceTextWriterStartChoice(mceTextWriter *w, const xmlChar *ns) {
+    int ret=xmlTextWriterStartElementNS(w->writer, _X("mce"), _X("Choice"), NULL);
+    if (-1!=ret) {
+        mceQNameLevel_t* qName=mceQNameLevelLookup(&w->registered_set, ns, NULL, PTRUE);
+        if (NULL!=qName) {
+            xmlTextWriterWriteAttribute(w->writer, _X("Requires"), qName->ln);
+        } else {
+            PASSERT(0); // namespace not registered
+            ret=-1;
+        }
+    }
+    return ret;
+}
+
+int mceTextWriterEndChoice(mceTextWriter *w) {
+    return xmlTextWriterEndElement(w->writer);
+}
+
+int mceTextWriterStartFallback(mceTextWriter *w) {
+    return xmlTextWriterStartElementNS(w->writer, _X("mce"), _X("AlternateContent"), NULL);
+}
+
+int mceTextWriterEndFallback(mceTextWriter *w) {
+    return xmlTextWriterEndElement(w->writer);
+}
+
+
+static int  xmlOutputWrite(void * context, const char * buffer, int len) {
+    FILE *out=(FILE*)context;
+    return fwrite(buffer, sizeof(char), len, out);
+}
+
+static int xmlOutputClose(void * context) {
+    return 0;
+}
+
+xmlTextWriterPtr xmlNewTextWriterFile(FILE *file) {
+    xmlTextWriter *writer=NULL;
+    if (NULL!=file) {
+        xmlOutputBuffer *out=xmlOutputBufferCreateIO(xmlOutputWrite, xmlOutputClose, file, NULL);
+        if (NULL!=out) {
+            writer=xmlNewTextWriter(out);
+        }
+    } else {
+        xmlOutputBuffer *out=xmlOutputBufferCreateIO(xmlOutputWrite, xmlOutputClose, stdout, NULL);
+        if (NULL!=out) {
+            writer=xmlNewTextWriter(out);
+        }
+    }
+    return writer;
+}
+
+mceTextWriter *mceNewTextWriterFile(FILE *file) {
+    return mceTextWriterCreateIO(xmlOutputWrite, xmlOutputClose, file, NULL);
+}
+
+xmlTextWriterPtr mceTextWriterIntern(mceTextWriter *w) {
+    return w->writer;
+}
+

+ 176 - 0
mce/textwriter.h

@@ -0,0 +1,176 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file mce/textwriter.h
+
+*/
+#include <mce/config.h>
+#include <libxml/xmlwriter.h>
+#include <mce/helper.h>
+
+#ifndef MCE_TEXTWRITER_H
+#define MCE_TEXTWRITER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+
+/**
+  Default flags for an MCE namespace declaration.
+  */
+#define MCE_DEFAULT 0x0
+
+/**
+  Flags MCE namespace declaration "ignorable".
+  */
+#define MCE_IGNORABLE 0x1
+
+/**
+  Flags MCE namespace declaration "must understand".
+  */
+#define MCE_MUSTUNDERSTAND 0x2
+
+    /**
+      The MCE text writer context.
+      */
+    typedef struct MCE_TEXTWRITER_STRUCT mceTextWriter;
+
+    /**
+      Create a new MCE text writer.
+      \see http://xmlsoft.org/html/libxml-xmlIO.html#xmlOutputBufferCreateIO
+      \see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlNewTextWriter
+      */
+    mceTextWriter *mceTextWriterCreateIO(xmlOutputWriteCallback iowrite, xmlOutputCloseCallback  ioclose, void *ioctx, xmlCharEncodingHandlerPtr encoder);
+
+    /**
+      Helper which create a new MCE text writer for a FILE handle.
+      */
+    mceTextWriter *mceNewTextWriterFile(FILE *file);
+
+    /**
+      Free all resources for \w.
+      */
+    int mceTextWriterFree(mceTextWriter *w);
+
+    /**
+      \see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterStartDocument
+      */
+    int mceTextWriterStartDocument(mceTextWriter *w);
+
+    /**
+      \see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterEndDocument
+      */
+    int mceTextWriterEndDocument(mceTextWriter *w);
+
+    /**
+      Start a new XML element. If ns==NULL then there is no namespace and ""==ns means the default namespace.
+      \see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterStartElement
+      \see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterStartElementNS
+      */
+    int mceTextWriterStartElement(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln);
+
+    /**
+      \see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterEndElement
+      */
+    int mceTextWriterEndElement(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln);
+
+    /**
+      \see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterWriteString
+      */
+    int mceTextWriterWriteString(mceTextWriter *w, const xmlChar *content);
+
+    /**
+      Register a namespace. Must be called before mceTextWriterStartElement.
+      \see MCE_DEFAULT
+      \see MCE_IGNORABLE
+      \see MCE_MUSTUNDERSTAND
+      */
+    const xmlChar *mceTextWriterRegisterNamespace(mceTextWriter *w, const xmlChar *ns, const xmlChar *prefix, int flags);
+
+    /**
+      Register qname (ns, ln) as a "process content" element wrt. MCE. Must be called before mceTextWriterStartElement.
+      */
+    int mceTextWriterProcessContent(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln);
+
+    /**
+      Writes a formatted attribute.
+      \see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterWriteFormatAttribute
+      */
+    int mceTextWriterAttributeF(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln, const char *value, ...);
+
+    /**
+      Starts an MCE alternate content section.
+      */
+    int mceTextWriterStartAlternateContent(mceTextWriter *w);
+
+    /**
+      Ends an MCE alternate content section.
+      */
+    int mceTextWriterEndAlternateContent(mceTextWriter *w);
+
+    /**
+      Start an MCE choice.
+      */
+    int mceTextWriterStartChoice(mceTextWriter *w, const xmlChar *ns);
+
+    /**
+      Ends an MCE choice.
+      */
+    int mceTextWriterEndChoice(mceTextWriter *w);
+
+    /**
+      Start an MCE fallback.
+      */
+    int mceTextWriterStartFallback(mceTextWriter *w);
+
+    /**
+      Ends an MCE fallback.
+      */
+    int mceTextWriterEndFallback(mceTextWriter *w);
+
+
+    /**
+      Returns the underlying xmlTextWriter.
+      */
+    xmlTextWriterPtr mceTextWriterIntern(mceTextWriter *w);
+
+    /**
+      Helper which create a new xmlTextWriterPtr for a FILE handle.
+      */
+    xmlTextWriterPtr xmlNewTextWriterFile(FILE *file);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+
+#endif /* MCE_TEXTWRITER_H */

+ 1 - 0
opc/..svnbridge/properties.c

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 1 - 0
opc/..svnbridge/properties.h

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 1496 - 0
opc/container.c

@@ -0,0 +1,1496 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+#include "internal.h"
+
+
+static void* ensureItem(void **array_, puint32_t items, puint32_t item_size) {
+    *array_=xmlRealloc(*array_, (items+1)*item_size);
+    return *array_;
+}
+
+static opcContainerPart* ensurePart(opcContainer *container) {
+    return ((opcContainerPart*)ensureItem((void**)&container->part_array, container->part_items, sizeof(opcContainerPart)))+container->part_items;
+}
+
+static opcContainerRelPrefix* ensureRelPrefix(opcContainer *container) {
+    return ((opcContainerRelPrefix*)ensureItem((void**)&container->relprefix_array, container->relprefix_items, sizeof(opcContainerRelPrefix)))+container->relprefix_items;
+}
+
+static opcContainerType* ensureType(opcContainer *container) {
+    return ((opcContainerType*)ensureItem((void**)&container->type_array, container->type_items, sizeof(opcContainerType)))+container->type_items;
+}
+
+static opcContainerExtension* ensureExtension(opcContainer *container) {
+    return ((opcContainerExtension*)ensureItem((void**)&container->extension_array, container->extension_items, sizeof(opcContainerExtension)))+container->extension_items;
+}
+
+static opcContainerRelationType* ensureRelationType(opcContainer *container) {
+    return ((opcContainerRelationType*)ensureItem((void**)&container->relationtype_array, container->relationtype_items, sizeof(opcContainerRelationType)))+container->relationtype_items;
+}
+
+static opcContainerExternalRelation* ensureExternalRelation(opcContainer *container) {
+    return ((opcContainerExternalRelation*)ensureItem((void**)&container->externalrelation_array, container->externalrelation_items, sizeof(opcContainerRelationType)))+container->externalrelation_items;
+}
+
+
+static opc_bool_t findItem(void *array_, opc_uint32_t items, const void *key1, opc_uint32_t key2, int (*cmp_fct)(const void *key1, opc_uint32_t key2, const void *array_, opc_uint32_t item), opc_uint32_t *pos) {
+    opc_uint32_t i=0;
+    opc_uint32_t j=items;
+    while(i<j) {
+        opc_uint32_t m=i+(j-i)/2;
+        OPC_ASSERT(i<=m && m<j);
+        int cmp=cmp_fct(key1, key2, array_, m);
+        if (cmp<0) {
+            j=m;
+        } else if (cmp>0) {
+            i=m+1;
+        } else {
+            *pos=m;
+            return OPC_TRUE;
+        }
+    }
+    OPC_ASSERT(i==j); 
+    *pos=i;
+    return OPC_FALSE;
+}
+
+#define ensureGap(array_, items_, i) \
+{\
+    for (opc_uint32_t k=items_;k>i;k--) { \
+        (array_)[k]=(array_)[k-1];\
+    }\
+    (items_)++;\
+    OPC_ASSERT(i>=0 && i<(items_));\
+    opc_bzero_mem(&(array_)[i], sizeof((array_)[i]));\
+}
+
+
+static inline int part_cmp_fct(const void *key, opc_uint32_t v, const void *array_, opc_uint32_t item) {
+    return xmlStrcmp((xmlChar*)key, ((opcContainerPart*)array_)[item].name);
+}
+
+
+opcContainerPart *opcContainerInsertPart(opcContainer *container, const xmlChar *name, opc_bool_t insert) {
+    opc_uint32_t i=0;
+    if (findItem(container->part_array, container->part_items, name, 0, part_cmp_fct, &i)) {
+        return &container->part_array[i];
+    } else if (insert && NULL!=ensurePart(container)) {
+        ensureGap(container->part_array, container->part_items, i);
+        container->part_array[i].first_segment_id=-1;
+        container->part_array[i].last_segment_id=-1;
+        container->part_array[i].name=xmlStrdup(name); 
+        container->part_array[i].rel_segment_id=-1;
+        return &container->part_array[i];
+    } else {
+        return NULL;
+    }
+}
+
+#define deleteItem(array_, items_, i) \
+{\
+    for(opc_uint32_t k=i+1;k<items_;k++) {\
+        array_[k-1]=array_[k];\
+    }\
+    items_--;\
+}
+
+
+static opc_error_t opcContainerDeleteAllRelationsToPart(opcContainer *container, opcPart part, opcContainerRelation **relation_array, opc_uint32_t *relation_items) {
+    for(opc_uint32_t i=0;i<*relation_items;) {
+        if (0==(*relation_array)[i].target_mode && part==(*relation_array)[i].target_ptr) {
+            deleteItem((*relation_array), (*relation_items), i);
+        } else {
+            i++;
+        }
+    }
+    return OPC_ERROR_NONE;
+}
+
+opc_error_t opcContainerDeletePart(opcContainer *container, const xmlChar *name) {
+    opc_error_t ret=OPC_ERROR_NONE;
+    opc_uint32_t i=0;
+    if (findItem(container->part_array, container->part_items, name, 0, part_cmp_fct, &i)) {
+        if (-1!=container->part_array[i].first_segment_id) {
+            opcContainerDeletePartEx(container, name, OPC_FALSE);
+        }
+        if (-1!=container->part_array[i].rel_segment_id) {
+            opcContainerDeletePartEx(container, name, OPC_TRUE);
+        }
+        OPC_ENSURE(OPC_ERROR_NONE==opcContainerDeleteAllRelationsToPart(container, container->part_array[i].name, &container->relation_array, &container->relation_items));
+        for(opc_uint32_t j=0;j<container->part_items;j++) {
+            OPC_ENSURE(OPC_ERROR_NONE==opcContainerDeleteAllRelationsToPart(container, container->part_array[i].name, &container->part_array[j].relation_array, &container->part_array[j].relation_items));
+        }
+        if (NULL!=container->part_array[i].relation_array){
+            xmlFree(container->part_array[i].relation_array);
+        }
+        if (NULL!=container->part_array[i].name){
+            xmlFree(container->part_array[i].name);   
+        }
+        deleteItem(container->part_array, container->part_items, i);
+    }
+    return ret;
+}
+
+#define OPC_MAX_UINT16 65535
+static opc_uint32_t insertRelPrefix(opcContainer *container, const xmlChar *relPrefix) {
+    opc_uint32_t i=container->relprefix_items; 
+    for(;i>0 && 0!=xmlStrcmp(container->relprefix_array[i-1].prefix, relPrefix);) {
+        i--;
+    };
+    if (i>0) {
+        OPC_ASSERT(0==xmlStrcmp(container->relprefix_array[i-1].prefix, relPrefix));
+        return i-1;
+    } else {
+        if (container->relprefix_items<OPC_MAX_UINT16 && NULL!=ensureRelPrefix(container)) {
+            i=container->relprefix_items++;
+            container->relprefix_array[i].prefix=xmlStrdup(relPrefix);
+            return i;
+        } else {
+            return -1; // error
+        }
+    }
+}
+
+static opc_uint32_t findRelPrefix(opcContainer *container, const xmlChar *relPrefix, opc_uint32_t relPrefixLen) {
+    for(opc_uint32_t i=0;i<=container->relprefix_items;i++) {
+        if (0==xmlStrncmp(container->relprefix_array[i].prefix, relPrefix, relPrefixLen) && 0==container->relprefix_array[i].prefix[relPrefixLen]) {
+            return i;
+        }
+    }
+    return -1; // not found
+}
+
+
+static opc_uint32_t splitRelPrefix(opcContainer *container, const xmlChar *rel, opc_uint32_t *counter) {
+    opc_uint32_t len=xmlStrlen(rel);
+    while(len>0 && rel[len-1]>='0' && rel[len-1]<='9') len--;
+    if (NULL!=counter) {
+        if (rel[len]!=0) {
+            *counter=atoi((char*)(rel+len));
+        } else {
+            *counter=-1; // no counter
+        }
+    }
+    return len;
+}
+
+static opc_uint32_t assembleRelId(opc_uint32_t prefix, opc_uint16_t relCounter) {
+    opc_uint32_t ret=relCounter;
+    if (-1!=prefix) {
+        ret|=prefix<<16;
+    } 
+    return ret;
+}
+
+static opc_uint32_t createRelId(opcContainer *container, const xmlChar *relPrefix, opc_uint16_t relCounter) {
+    opc_uint32_t prefix=insertRelPrefix(container, relPrefix);
+    opc_uint32_t ret=assembleRelId(prefix, relCounter);
+    return ret;
+}
+
+
+static inline int type_cmp_fct(const void *key, opc_uint32_t v, const void *array_, opc_uint32_t item) {
+    return xmlStrcmp((xmlChar*)key, ((opcContainerType*)array_)[item].type);
+}
+
+opcContainerType *insertType(opcContainer *container, const xmlChar *type, opc_bool_t insert) {
+    opc_uint32_t i=0;
+    if (findItem(container->type_array, container->type_items, type, 0, type_cmp_fct, &i)) {
+        return &container->type_array[i];
+    } else if (insert && NULL!=ensureType(container)) {
+        ensureGap(container->type_array, container->type_items, i);
+        container->type_array[i].type=xmlStrdup(type);
+        return &container->type_array[i];
+    } else {
+        return NULL;
+    }
+}
+
+static inline int extension_cmp_fct(const void *key, opc_uint32_t v, const void *array_, opc_uint32_t item) {
+    return xmlStrcmp((xmlChar*)key, ((opcContainerExtension*)array_)[item].extension);
+}
+
+opcContainerExtension *opcContainerInsertExtension(opcContainer *container, const xmlChar *extension, opc_bool_t insert) {
+    opc_uint32_t i=0;
+    if (findItem(container->extension_array, container->extension_items, extension, 0, extension_cmp_fct, &i)) {
+        return &container->extension_array[i];
+    } else if (insert && NULL!=ensureExtension(container)) {
+        ensureGap(container->extension_array, container->extension_items, i);
+        container->extension_array[i].extension=xmlStrdup(extension);
+        return &container->extension_array[i];
+    } else {
+        return NULL;
+    }
+}
+
+static inline int relationtype_cmp_fct(const void *key, opc_uint32_t v, const void *array_, opc_uint32_t item) {
+    return xmlStrcmp((xmlChar*)key, ((opcContainerRelationType*)array_)[item].type);
+}
+opcContainerRelationType *opcContainerInsertRelationType(opcContainer *container, const xmlChar *type, opc_bool_t insert) {
+    opc_uint32_t i=0;
+    if (findItem(container->relationtype_array, container->relationtype_items, type, 0, relationtype_cmp_fct, &i)) {
+        return &container->relationtype_array[i];
+    } else if (insert && NULL!=ensureRelationType(container)) {
+        ensureGap(container->relationtype_array, container->relationtype_items, i);
+        container->relationtype_array[i].type=xmlStrdup(type);
+        return &container->relationtype_array[i];
+    } else {
+        return NULL;
+    }
+}
+
+static inline int externalrelation_cmp_fct(const void *key, opc_uint32_t v, const void *array_, opc_uint32_t item) {
+    return xmlStrcmp((xmlChar*)key, ((opcContainerExternalRelation*)array_)[item].target);
+}
+
+opcContainerExternalRelation*insertExternalRelation(opcContainer *container, const xmlChar *target, opc_bool_t insert) {
+    opc_uint32_t i=0;
+    if (findItem(container->externalrelation_array, container->externalrelation_items, target, 0, externalrelation_cmp_fct, &i)) {
+        return &container->externalrelation_array[i];
+    } else if (insert && NULL!=ensureExternalRelation(container)) {
+        ensureGap(container->externalrelation_array, container->externalrelation_items, i);
+        container->externalrelation_array[i].target=xmlStrdup(target);
+        return &container->externalrelation_array[i];
+    } else {
+        return NULL;
+    }
+}
+
+
+static inline int relation_cmp_fct(const void *key, opc_uint32_t v, const void *array_, opc_uint32_t item) {
+    opcRelation r1=v;
+    opcRelation r2=((opcContainerRelation*)array_)[item].relation_id;
+    if (OPC_CONTAINER_RELID_PREFIX(r1)==OPC_CONTAINER_RELID_PREFIX(r2)) {
+        if (OPC_CONTAINER_RELID_COUNTER_NONE==OPC_CONTAINER_RELID_COUNTER(r1)) {
+            return (OPC_CONTAINER_RELID_COUNTER_NONE==OPC_CONTAINER_RELID_COUNTER(r2)?0:-1);
+        } else if (OPC_CONTAINER_RELID_COUNTER_NONE==OPC_CONTAINER_RELID_COUNTER(r2)) {
+            OPC_ASSERT(OPC_CONTAINER_RELID_COUNTER_NONE!=OPC_CONTAINER_RELID_COUNTER(r1));
+            return 1;
+        } else {
+            OPC_ASSERT(OPC_CONTAINER_RELID_COUNTER_NONE!=OPC_CONTAINER_RELID_COUNTER(r1) && OPC_CONTAINER_RELID_COUNTER_NONE!=OPC_CONTAINER_RELID_COUNTER(r2));
+            return OPC_CONTAINER_RELID_COUNTER(r1)-OPC_CONTAINER_RELID_COUNTER(r2);
+        }
+    } else {
+        return OPC_CONTAINER_RELID_PREFIX(r1)-OPC_CONTAINER_RELID_PREFIX(r2);
+    }
+}
+opcContainerRelation *opcContainerInsertRelation(opcContainerRelation **relation_array, opc_uint32_t *relation_items, 
+                                            opc_uint32_t relation_id,
+                                            xmlChar *relation_type,
+                                            opc_uint32_t target_mode, xmlChar *target_ptr) {
+    OPC_ASSERT(NULL!=relation_items);
+    opc_uint32_t i=0;
+    if (*relation_items>0) {
+        opc_bool_t ret=findItem(*relation_array, *relation_items, NULL, relation_id, relation_cmp_fct, &i);
+        if (ret) { // error, relation already exists!
+            return NULL;
+        }
+    }
+    if (NULL!=ensureItem((void**)relation_array, *relation_items, sizeof(opcContainerRelation))) {
+        for (opc_uint32_t k=(*relation_items);k>i;k--) { 
+            (*relation_array)[k]=(*relation_array)[k-1];
+        }
+        (*relation_items)++;
+        OPC_ASSERT(i>=0 && i<(*relation_items));\
+        opc_bzero_mem(&(*relation_array)[i], sizeof((*relation_array)[i]));\
+        (*relation_array)[i].relation_id=relation_id;
+        (*relation_array)[i].relation_type=relation_type;
+        (*relation_array)[i].target_mode=target_mode;
+        (*relation_array)[i].target_ptr=target_ptr;
+        return &(*relation_array)[i];
+    } else {
+        return NULL; // memory error!
+    }
+}
+
+opcContainerRelation *opcContainerFindRelation(opcContainer *container, opcContainerRelation *relation_array, opc_uint32_t relation_items, opcRelation relation) {
+    opc_uint32_t i=0;
+    opc_bool_t ret=findItem(relation_array, relation_items, NULL, relation, relation_cmp_fct, &i);
+    return (ret?&relation_array[i]:NULL);
+}
+
+opc_error_t opcContainerDeleteRelation(opcContainer *container, opcContainerRelation **relation_array, opc_uint32_t *relation_items, opcRelation relation) {
+    opc_error_t err=OPC_ERROR_NONE;
+    opc_uint32_t i=0;
+    opc_bool_t ret=findItem(*relation_array, *relation_items, NULL, relation, relation_cmp_fct, &i);
+    if (ret) {
+        deleteItem((*relation_array), (*relation_items), i);
+    }
+    return err;
+}
+
+
+opcContainerRelation *opcContainerFindRelationById(opcContainer *container, opcContainerRelation *relation_array, opc_uint32_t relation_items, const xmlChar *relation_id) {
+    opc_uint32_t counter=-1;
+    opc_uint32_t id_len=splitRelPrefix(container, relation_id, &counter);
+    opc_uint32_t rel=-1;
+    if (id_len>0) {
+        opc_uint32_t prefix=findRelPrefix(container, relation_id, id_len);
+        if (-1!=prefix) {
+            rel=assembleRelId(prefix, counter);
+        }
+    } else {
+        rel=assembleRelId(-1, counter);
+    }
+
+    opcContainerRelation *ret=(-1!=rel?opcContainerFindRelation(container, relation_array, relation_items, rel):NULL);
+    return ret;
+}
+
+
+
+static void opc_container_normalize_part_to_helper_buffer(xmlChar *buf, int buf_len,
+                                                          const xmlChar *base,
+                                                          const xmlChar *name) {
+  int j=xmlStrlen(base);
+  int i=0;
+  OPC_ASSERT(j<=buf_len);
+  if (j>0) {
+    memcpy(buf, base, j*sizeof(xmlChar));
+  }
+  while(j>0 && buf[j-1]!='/') j--;  // so make sure base has a trailing "/"
+  
+  while(name[i]!=0) {
+    if (name[i]=='/') {
+      j=0; /* absolute path */
+      while (name[i]=='/') i++;
+    } else if (name[i]=='.' && name[i+1]=='/') {
+      /* skip */
+      i+=1;
+      while (name[i]=='/') i++;
+    } else if (name[i]=='.' && name[i+1]=='.' && name[i+2]=='/') {
+      while(j>0 &&  buf[j-1]=='/') j--; /* skip base '/' */
+      while(j>0 &&  buf[j-1]!='/') j--; /* navigate one dir up */
+      i+=2;
+      while (name[i]=='/') i++;
+    } else {
+      /* copy step */
+      OPC_ASSERT(j+1<=buf_len);
+      while(j+1<buf_len && name[i]!=0 && name[i]!='/') {
+        buf[j++]=name[i++];
+      }
+      if (name[i]=='/' && j+1<buf_len) {
+        buf[j++]='/';
+      }
+      while (name[i]=='/') i++;
+    }
+  }
+  OPC_ASSERT(j+1<buf_len);
+  buf[j]=0;
+}
+
+static void opcConstainerParseRels(opcContainer *c, const xmlChar *partName, opcContainerRelation **relation_array, opc_uint32_t *relation_items) {
+    mceTextReader_t reader;
+    if (OPC_ERROR_NONE==opcXmlReaderOpenEx(c, &reader, partName, OPC_TRUE, NULL, NULL, 0)) {
+        static const char ns[]="http://schemas.openxmlformats.org/package/2006/relationships";
+        mce_start_document(&reader) {
+            mce_start_element(&reader, _X(ns), _X("Relationships")) {
+                mce_skip_attributes(&reader);
+                mce_start_children(&reader) {
+                    mce_start_element(&reader, NULL, _X("Relationship")) {
+                        const xmlChar *id=NULL;
+                        const xmlChar *type=NULL;
+                        const xmlChar *target=NULL;
+                        const xmlChar *mode=NULL;
+                        mce_start_attributes(&reader) {
+                            mce_start_attribute(&reader, NULL, _X("Id")) {
+                                id=xmlTextReaderConstValue(reader.reader);
+                            } mce_end_attribute(&reader);
+                            mce_start_attribute(&reader, NULL, _X("Type")) {
+                                type=xmlTextReaderConstValue(reader.reader);
+                            } mce_end_attribute(&reader);
+                            mce_start_attribute(&reader, NULL, _X("Target")) {
+                                target=xmlTextReaderConstValue(reader.reader);
+                            } mce_end_attribute(&reader);
+                            mce_start_attribute(&reader, NULL, _X("TargetMode")) {
+                                mode=xmlTextReaderConstValue(reader.reader);
+                            }
+                        } mce_end_attributes(&reader);
+                        mce_error_guard_start(&reader) {
+                            mce_error(&reader, NULL==id || id[0]==0, MCE_ERROR_VALIDATION, "Missing @Id attribute!");
+                            mce_error(&reader, NULL==type || type[0]==0, MCE_ERROR_VALIDATION, "Missing @Type attribute!");
+                            mce_error(&reader, NULL==target || target[0]==0, MCE_ERROR_VALIDATION, "Missing @Id attribute!");
+                            opcContainerRelationType *rel_type=opcContainerInsertRelationType(c, type, OPC_TRUE);
+                            mce_error(&reader, NULL==rel_type, MCE_ERROR_MEMORY, NULL);
+                            opc_uint32_t counter=-1;
+                            opc_uint32_t id_len=splitRelPrefix(c, id, &counter);
+                            ((xmlChar *)id)[id_len]=0;
+                            opc_uint32_t rel_id=createRelId(c, id, counter);
+                            if (NULL==mode || 0==xmlStrcasecmp(mode, _X("Internal"))) {
+                                xmlChar target_part_name[OPC_MAX_PATH];
+                                opc_container_normalize_part_to_helper_buffer(target_part_name, sizeof(target_part_name), partName, target);
+        //                        printf("%s (%s;%s)\n", target_part_name, base, target);
+                                opcContainerPart *target_part=opcContainerInsertPart(c, target_part_name, OPC_FALSE);
+                                mce_errorf(&reader, NULL==target_part, MCE_ERROR_VALIDATION, "Referenced part %s (%s;%s) does not exists!", target_part_name, partName, target);
+    //                            printf("%s %i %s %s\n", id, counter, rel_type->type, target_part->name);
+                                opcContainerRelation *rel=opcContainerInsertRelation(relation_array, relation_items, rel_id, rel_type->type, 0, target_part->name);
+                                OPC_ASSERT(NULL!=rel);
+                            } else if (0==xmlStrcasecmp(mode, _X("External"))) {
+                                opcContainerExternalRelation *ext_rel=insertExternalRelation(c, target, OPC_TRUE);
+                                mce_error(&reader, NULL==ext_rel, MCE_ERROR_MEMORY, NULL);
+                                opcContainerRelation *rel=opcContainerInsertRelation(relation_array, relation_items, rel_id, rel_type->type, 1, ext_rel->target);
+                                OPC_ASSERT(NULL!=rel);
+                            } else {
+                                mce_errorf(&reader, OPC_TRUE, MCE_ERROR_VALIDATION, "TargetMode %s unknown!\n", mode);
+                            }
+                        } mce_error_guard_end(reader);
+                        mce_skip_children(&reader);
+                    } mce_end_element(&reader);
+                } mce_end_children(&reader);
+            } mce_end_element(&reader);
+        } mce_end_document(reader);
+        OPC_ENSURE(0==mceTextReaderCleanup(&reader));
+    }
+}
+
+static const xmlChar OPC_SEGMENT_CONTENTTYPES[]={'[', 'C', 'o', 'n', 't', 'e', 'n', 't', '_', 'T', 'y', 'p', 'e', 's', ']', '.', 'x', 'm', 'l', 0};
+static const xmlChar OPC_SEGMENT_ROOTRELS[]={0};
+
+static opc_error_t opcContainerFree(opcContainer *c) {
+    if (NULL!=c) {
+        for(opc_uint32_t i=0;i<c->extension_items;i++) {
+            xmlFree(c->extension_array[i].extension);
+        }
+        for(opc_uint32_t i=0;i<c->type_items;i++) {
+            xmlFree(c->type_array[i].type);
+        }
+        for(opc_uint32_t i=0;i<c->relationtype_items;i++) {
+            xmlFree(c->relationtype_array[i].type);
+        }
+        for(opc_uint32_t i=0;i<c->externalrelation_items;i++) {
+            xmlFree(c->externalrelation_array[i].target);
+        }
+        for(opc_uint32_t i=0;i<c->part_items;i++) {
+            xmlFree(c->part_array[i].relation_array);
+            xmlFree(c->part_array[i].name);
+        }
+        for(opc_uint32_t i=0;i<c->relprefix_items;i++) {
+            xmlFree(c->relprefix_array[i].prefix);
+        }
+        if (NULL!=c->part_array) xmlFree(c->part_array);
+        if (NULL!=c->relprefix_array) xmlFree(c->relprefix_array);
+        if (NULL!=c->type_array) xmlFree(c->type_array);
+        if (NULL!=c->extension_array) xmlFree(c->extension_array);
+        if (NULL!=c->relationtype_array) xmlFree(c->relationtype_array);
+        if (NULL!=c->externalrelation_array) xmlFree(c->externalrelation_array);
+        if (NULL!=c->relation_array) xmlFree(c->relation_array);
+        opcZipClose(c->storage, NULL);
+        xmlFree(c);
+    }
+    return OPC_ERROR_NONE;
+}
+
+static void opcContainerDumpString(FILE *out, const xmlChar *str, opc_uint32_t max_len, opc_bool_t new_line) {
+    opc_uint32_t len=(NULL!=str?xmlStrlen(str):0);
+    if (len<=max_len) {
+        if (NULL!=str) fputs((const char *)str, out);
+        for(opc_uint32_t i=len;i<max_len;i++) fputc(' ', out);
+    } else {
+        static const char prefix[]="...";
+        static opc_uint32_t prefix_len=sizeof(prefix)-1;
+        opc_uint32_t ofs=len-max_len;
+        if (ofs+prefix_len<len) ofs+=prefix_len; else ofs=len;
+        fputs(prefix, out);
+        fputs((const char *)(str+ofs), out);
+    }
+    if (new_line) {
+        fputc('\n', out);
+    }
+}
+
+static void opcContainerDumpLine(FILE *out, const xmlChar line_char, opc_uint32_t max_len, opc_bool_t new_line) {
+    for(opc_uint32_t i=0;i<max_len;i++) {
+        fputc(line_char, out);
+    }
+    if (new_line) {
+        fputc('\n', out);
+    }
+}
+
+
+static void opcContainerRelCalcMax(opcContainer *c, 
+                                   const xmlChar *part_name,
+                                   opcContainerRelation *relation_array, opc_uint32_t relation_items, 
+                                   opc_uint32_t *max_rel_src,
+                                   opc_uint32_t *max_rel_id,
+                                   opc_uint32_t *max_rel_dest,
+                                   opc_uint32_t *max_rel_type) {
+    if (relation_items>0) {
+        opc_uint32_t const src_len=xmlStrlen(part_name); 
+        if (src_len>*max_rel_src) *max_rel_src=src_len;
+        for(opc_uint32_t j=0;j<relation_items;j++) {
+            const xmlChar *prefix=NULL;
+            opc_uint32_t counter=-1;
+            const xmlChar *type=NULL;
+            char buf[20]="";
+            opcRelationGetInformation(c, (opcPart)part_name, relation_array[j].relation_id, &prefix, &counter, &type);
+            if (-1!=counter) {
+                sprintf(buf, "%i", counter);
+            }
+            opc_uint32_t const type_len=xmlStrlen(type); 
+            if (type_len>*max_rel_type) *max_rel_type=type_len;
+            opc_uint32_t const id_len=xmlStrlen(prefix)+xmlStrlen(_X(buf)); 
+            if (id_len>*max_rel_id) *max_rel_id=id_len;
+            opc_uint32_t const dest_len=xmlStrlen(relation_array[j].target_ptr); 
+            if (dest_len>*max_rel_dest) *max_rel_dest=dest_len;
+        }
+    }
+}
+
+static void opcContainerRelDump(opcContainer *c, 
+                                FILE *out,
+                                const xmlChar *part_name,
+                                opcContainerRelation *relation_array, opc_uint32_t relation_items, 
+                                opc_uint32_t max_rel_src,
+                                opc_uint32_t max_rel_id,
+                                opc_uint32_t max_rel_dest,
+                                opc_uint32_t max_rel_type) {
+    for(opc_uint32_t j=0;j<relation_items;j++) {
+        opcContainerDumpString(out, (part_name==NULL?_X("[root]"):part_name), max_rel_src, OPC_FALSE); fputc('|', out);
+        const xmlChar *prefix=NULL;
+        opc_uint32_t counter=-1;
+        const xmlChar *type=NULL;
+        char buf[20]="";
+        opcRelationGetInformation(c, (opcPart)part_name, relation_array[j].relation_id, &prefix, &counter, &type);
+        if (-1!=counter) {
+            sprintf(buf, "%i", counter);
+        }
+        opc_uint32_t prefix_len=xmlStrlen(prefix);
+        opcContainerDumpString(out, prefix, prefix_len, OPC_FALSE);
+        OPC_ASSERT(xmlStrlen(_X(buf))+prefix_len<=max_rel_id);
+        opcContainerDumpString(out, _X(buf), max_rel_id-prefix_len, OPC_FALSE); fputc('|', out);
+        opcContainerDumpString(out, relation_array[j].target_ptr, max_rel_dest, OPC_FALSE); fputc('|', out);
+        opcContainerDumpString(out, type, max_rel_type, OPC_TRUE);
+    }
+}
+
+opc_error_t opcContainerDump(opcContainer *c, FILE *out) {
+    opc_uint32_t max_content_type_len=xmlStrlen(_X("Content Types")); 
+    for(opc_uint32_t i=0;i<c->type_items;i++) { 
+        opc_uint32_t const len=xmlStrlen(c->type_array[i].type); 
+        if (len>max_content_type_len) max_content_type_len=len;
+    }
+    opc_uint32_t max_extension_len=xmlStrlen(_X("Extension")); 
+    opc_uint32_t max_extension_type_len=xmlStrlen(_X("Type")); 
+    for(opc_uint32_t i=0;i<c->extension_items;i++) { 
+        opc_uint32_t const len=xmlStrlen(c->extension_array[i].extension); 
+        if (len>max_extension_len) max_extension_len=len;
+        opc_uint32_t const type_len=xmlStrlen(c->extension_array[i].type); 
+        if (type_len>max_extension_type_len) max_extension_type_len=type_len;
+    }
+    opc_uint32_t max_rel_type_len=xmlStrlen(_X("Relation Types")); 
+    for(opc_uint32_t i=0;i<c->relationtype_items;i++) { 
+        opc_uint32_t const len=xmlStrlen(c->relationtype_array[i].type); 
+        if (len>max_rel_type_len) max_rel_type_len=len;
+    }
+
+    opc_uint32_t max_ext_rel_len=xmlStrlen(_X("External Relations")); 
+    for(opc_uint32_t i=0;i<c->externalrelation_items;i++) { 
+        opc_uint32_t const len=xmlStrlen(c->externalrelation_array[i].target); 
+        if (len>max_ext_rel_len) max_ext_rel_len=len;
+    }
+    opc_uint32_t max_part_name=xmlStrlen(_X("Part")); 
+    opc_uint32_t max_part_type=xmlStrlen(_X("Type")); 
+    for(opc_uint32_t i=0;i<c->part_items;i++) { 
+        if (-1!=c->part_array[i].first_segment_id) { // deleted?
+            opc_uint32_t const name_len=xmlStrlen(c->part_array[i].name); 
+            if (name_len>max_part_name) max_part_name=name_len;
+            opc_uint32_t const type_len=xmlStrlen(opcPartGetType(c, c->part_array[i].name)); 
+            if (type_len>max_part_type) max_part_type=type_len;
+        }
+    }
+
+    opc_uint32_t max_rel_src=xmlStrlen(_X("Source")); 
+    opc_uint32_t max_rel_id=xmlStrlen(_X("Id")); 
+    opc_uint32_t max_rel_dest=xmlStrlen(_X("Destination")); 
+    opc_uint32_t max_rel_type=xmlStrlen(_X("Type")); 
+    if (c->relationtype_items>0) {
+        opc_uint32_t const src_len=xmlStrlen(_X("[root]")); 
+        if (src_len>max_rel_src) max_rel_src=src_len;
+        opcContainerRelCalcMax(c, NULL, c->relation_array, c->relation_items, &max_rel_src, &max_rel_id, &max_rel_dest, &max_rel_type);
+    }
+    for(opc_uint32_t i=0;i<c->part_items;i++) { 
+        if (c->part_array[i].relation_items>0) {
+            opcContainerRelCalcMax(c, 
+                                   c->part_array[i].name, 
+                                   c->part_array[i].relation_array, c->part_array[i].relation_items, 
+                                   &max_rel_src, 
+                                   &max_rel_id, 
+                                   &max_rel_dest, 
+                                   &max_rel_type);
+        }
+    }
+
+    opcContainerDumpString(out, _X("Content Types"), max_content_type_len, OPC_TRUE);
+    opcContainerDumpLine(out, '-', max_content_type_len, OPC_TRUE);
+    for(opc_uint32_t i=0;i<c->type_items;i++) {
+        opcContainerDumpString(out, c->type_array[i].type, max_content_type_len, OPC_TRUE);
+    }
+    opcContainerDumpLine(out, '-', max_content_type_len, OPC_TRUE);
+    opcContainerDumpString(out, _X(""), 0, OPC_TRUE);
+
+    opcContainerDumpString(out, _X("Extension"), max_extension_len, OPC_FALSE); fputc('|', out);
+    opcContainerDumpString(out, _X("Type"), max_extension_type_len, OPC_TRUE);
+    opcContainerDumpLine(out, '-', max_extension_len, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_extension_type_len, OPC_TRUE);
+    for(opc_uint32_t i=0;i<c->extension_items;i++) {
+        opcContainerDumpString(out, c->extension_array[i].extension, max_extension_len, OPC_FALSE); fputc('|', out);
+        opcContainerDumpString(out, c->extension_array[i].type, max_extension_type_len, OPC_TRUE);
+    }
+    opcContainerDumpLine(out, '-', max_extension_len, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_extension_type_len, OPC_TRUE);
+    opcContainerDumpString(out, _X(""), 0, OPC_TRUE);
+
+    opcContainerDumpString(out, _X("Relation Types"), max_rel_type_len, OPC_TRUE);
+    opcContainerDumpLine(out, '-', max_rel_type_len, OPC_TRUE);
+    for(opc_uint32_t i=0;i<c->relationtype_items;i++) {
+        opcContainerDumpString(out, c->relationtype_array[i].type, max_rel_type_len, OPC_TRUE);
+    }
+    opcContainerDumpLine(out, '-', max_rel_type_len, OPC_TRUE);
+    opcContainerDumpString(out, _X(""), 0, OPC_TRUE);
+
+    opcContainerDumpString(out, _X("External Relations"), max_ext_rel_len, OPC_TRUE);
+    opcContainerDumpLine(out, '-', max_ext_rel_len, OPC_TRUE);
+    for(opc_uint32_t i=0;i<c->externalrelation_items;i++) {
+        opcContainerDumpString(out, c->externalrelation_array[i].target, max_ext_rel_len, OPC_TRUE);
+    }
+    opcContainerDumpLine(out, '-', max_ext_rel_len, OPC_TRUE);
+    opcContainerDumpString(out, _X(""), 0, OPC_TRUE);
+
+    opcContainerDumpString(out, _X("Part"), max_part_name, OPC_FALSE); fputc('|', out);
+    opcContainerDumpString(out, _X("Type"), max_part_type, OPC_TRUE);
+    opcContainerDumpLine(out, '-', max_part_name, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_part_type, OPC_TRUE);
+    for(opc_uint32_t i=0;i<c->part_items;i++) {
+        if (-1!=c->part_array[i].first_segment_id) { // deleted?
+            opcContainerDumpString(out, c->part_array[i].name, max_part_name, OPC_FALSE); fputc('|', out);
+            opcContainerDumpString(out, opcPartGetType(c, c->part_array[i].name), max_part_type, OPC_TRUE);
+        }
+    }
+    opcContainerDumpLine(out, '-', max_part_name, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_part_type, OPC_TRUE);
+    opcContainerDumpString(out, _X(""), 0, OPC_TRUE);
+
+    opcContainerDumpString(out, _X("Source"), max_rel_src, OPC_FALSE); fputc('|', out);
+    opcContainerDumpString(out, _X("Id"), max_rel_id, OPC_FALSE); fputc('|', out);
+    opcContainerDumpString(out, _X("Destination"), max_rel_dest, OPC_FALSE); fputc('|', out);
+    opcContainerDumpString(out, _X("Type"), max_rel_type, OPC_TRUE);
+    opcContainerDumpLine(out, '-', max_rel_src, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_rel_id, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_rel_dest, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_rel_type, OPC_TRUE);
+    if (c->relation_items>0) {
+        opcContainerRelDump(c, 
+                            out, 
+                            NULL, 
+                            c->relation_array, 
+                            c->relation_items, 
+                            max_rel_src, 
+                            max_rel_id, 
+                            max_rel_dest, 
+                            max_rel_type);
+    }
+    for(opc_uint32_t i=0;i<c->part_items;i++) { 
+        if (-1!=c->part_array[i].first_segment_id && c->part_array[i].relation_items>0) {
+            opcContainerRelDump(c, 
+                                out,
+                                c->part_array[i].name, 
+                                c->part_array[i].relation_array, c->part_array[i].relation_items, 
+                                max_rel_src, 
+                                max_rel_id, 
+                                max_rel_dest, 
+                                max_rel_type);
+        }
+    }
+    opcContainerDumpLine(out, '-', max_rel_src, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_rel_id, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_rel_dest, OPC_FALSE); fputc('|', out);
+    opcContainerDumpLine(out, '-', max_rel_type, OPC_TRUE);
+
+    return OPC_ERROR_NONE;
+}
+
+static opc_error_t opcContainerZipLoaderLoadSegment(void *iocontext, 
+                              void *userctx, 
+                              opcZipSegmentInfo_t *info, 
+                              opcZipLoaderOpenCallback *open, 
+                              opcZipLoaderReadCallback *read, 
+                              opcZipLoaderCloseCallback *close, 
+                              opcZipLoaderSkipCallback *skip) {
+    opc_error_t err=OPC_ERROR_NONE;
+    opcContainer *c=(opcContainer *)userctx;
+    OPC_ENSURE(0==skip(iocontext));
+    if (info->rels_segment) {
+        if (info->name[0]==0) {
+            OPC_ASSERT(-1==c->rels_segment_id); // loaded twice??
+            c->rels_segment_id=opcZipLoadSegment(c->storage, OPC_SEGMENT_ROOTRELS, info->rels_segment, info);
+            OPC_ASSERT(-1!=c->rels_segment_id); // not loaded??
+        } else {
+            opcContainerPart *part=opcContainerInsertPart(c, info->name, OPC_TRUE);
+            if (NULL!=part) {
+                OPC_ASSERT(-1==part->rel_segment_id); // loaded twice??
+                OPC_ASSERT(NULL!=part->name); // no name given???
+                part->rel_segment_id=opcZipLoadSegment(c->storage, part->name, info->rels_segment, info);
+                OPC_ASSERT(-1!=part->rel_segment_id);  // not loaded???
+            } else {
+                err=OPC_ERROR_MEMORY;
+            }
+        }
+    } else if (xmlStrcmp(info->name, OPC_SEGMENT_CONTENTTYPES)==0) {
+        OPC_ASSERT(-1==c->content_types_segment_id); // loaded twice??
+        c->content_types_segment_id=opcZipLoadSegment(c->storage, OPC_SEGMENT_CONTENTTYPES, info->rels_segment, info);
+        OPC_ASSERT(-1!=c->content_types_segment_id); // not loaded??
+    } else {
+        opcContainerPart *part=opcContainerInsertPart(c, info->name, OPC_TRUE);
+        if (NULL!=part) {
+            OPC_ASSERT(-1==part->first_segment_id); // loaded twice???
+            OPC_ASSERT(NULL!=part->name); // no name given???
+            part->first_segment_id=opcZipLoadSegment(c->storage, part->name, info->rels_segment, info);
+            OPC_ASSERT(-1!=part->first_segment_id);  // not loaded???
+            part->last_segment_id=part->first_segment_id;
+
+            if (info->name_len>0 && ('/'==info->name[info->name_len-1] || '\\'==info->name[info->name_len-1])) {
+                // it is a directoy, get rid of it...
+                opcContainerDeletePartEx(c, part->name, info->rels_segment);
+                OPC_ASSERT(-1==part->first_segment_id && -1==part->last_segment_id);
+                part=NULL; // no longer valid
+            }
+        } else {
+            err=OPC_ERROR_MEMORY;
+        }
+    }
+    return err;
+}
+
+static void opcContainerGetOutputPartSegment(opcContainer *container, const xmlChar *name, opc_bool_t rels_segment, opc_uint32_t **first_segment_ref, opc_uint32_t **last_segment_ref) {
+    if (OPC_SEGMENT_CONTENTTYPES==name) {
+        OPC_ASSERT(!rels_segment);
+        *first_segment_ref=&container->content_types_segment_id;
+        *last_segment_ref=NULL;
+    } else if (OPC_SEGMENT_ROOTRELS==name) {
+        OPC_ASSERT(rels_segment);
+        *first_segment_ref=&container->rels_segment_id;
+        *last_segment_ref=NULL;
+    } else {
+        opcContainerPart *part=opcContainerInsertPart(container, name, OPC_FALSE);
+        if (NULL!=part) {
+            if (rels_segment) {
+                *first_segment_ref=&part->rel_segment_id;
+                *last_segment_ref=NULL;
+            } else {
+                *first_segment_ref=&part->first_segment_id;
+                *last_segment_ref=&part->last_segment_id;
+            }
+        } else {
+            OPC_ASSERT(OPC_FALSE); // should not happen
+            *first_segment_ref=NULL;
+            *last_segment_ref=NULL;
+        }
+    }
+}
+
+
+opcContainerInputStream* opcContainerOpenInputStreamEx(opcContainer *container, const xmlChar *name, opc_bool_t rels_segment) {
+    opcContainerInputStream* ret=NULL;
+    opc_uint32_t *first_segment=NULL;
+    opc_uint32_t *last_segment=NULL;
+    opcContainerGetOutputPartSegment(container, name, rels_segment, &first_segment, &last_segment);
+    OPC_ASSERT(NULL!=first_segment);
+    if (NULL!=first_segment) {
+        ret=(opcContainerInputStream*)xmlMalloc(sizeof(opcContainerInputStream));
+        if (NULL!=ret) {
+            opc_bzero_mem(ret, sizeof(*ret));
+            ret->container=container;
+            ret->stream=opcZipOpenInputStream(container->storage, *first_segment);
+            if (NULL==ret->stream) {
+                xmlFree(ret); ret=NULL; // error
+            }
+        }
+    }
+    return ret;
+}
+
+opcContainerInputStream* opcContainerOpenInputStream(opcContainer *container, const xmlChar *name) {
+    return opcContainerOpenInputStreamEx(container, name, OPC_FALSE);
+}
+
+opc_uint32_t opcContainerReadInputStream(opcContainerInputStream* stream, opc_uint8_t *buffer, opc_uint32_t buffer_len) {
+    return opcZipReadInputStream(stream->container->storage, stream->stream, buffer, buffer_len);
+}
+
+opc_error_t opcContainerCloseInputStream(opcContainerInputStream* stream) {
+    opc_error_t ret=opcZipCloseInputStream(stream->container->storage, stream->stream);
+    xmlFree(stream);
+    return ret;
+}
+
+opcCompressionOption_t opcContainerGetInputStreamCompressionOption(opcContainerInputStream* stream) {
+    opcCompressionOption_t ret=OPC_COMPRESSIONOPTION_NONE;
+    if (8==stream->stream->inflateState.compression_method) {
+        // for now its just enough to know that we have a compression...
+        ret=OPC_COMPRESSIONOPTION_NORMAL; //@TODO look at stream to figure out real compression i.e. NORMAL, FAST, etc...
+    }
+    return ret;
+}
+
+
+opcContainerOutputStream* opcContainerCreateOutputStreamEx(opcContainer *container, const xmlChar *name, opc_bool_t rels_segment, opcCompressionOption_t compression_option) {
+    opcContainerOutputStream* ret=NULL;
+    opc_uint32_t *first_segment=NULL;
+    opc_uint32_t *last_segment=NULL;
+    opcContainerGetOutputPartSegment(container, name, rels_segment, &first_segment, &last_segment);
+    OPC_ASSERT(NULL!=first_segment);
+    if (NULL!=first_segment) {
+        ret=(opcContainerOutputStream*)xmlMalloc(sizeof(opcContainerOutputStream));
+        if (NULL!=ret) {
+            opc_bzero_mem(ret, sizeof(*ret));
+            ret->container=container;
+            opc_uint16_t compression_method=0; // no compression by default
+            opc_uint16_t bit_flag=0;
+            switch(compression_option) {
+            case OPC_COMPRESSIONOPTION_NONE:
+                OPC_ASSERT(0==compression_method);
+                OPC_ASSERT(0==bit_flag);
+                break;
+            case OPC_COMPRESSIONOPTION_NORMAL:
+                compression_method=8;
+                bit_flag|=0<<1;
+                break;
+            case OPC_COMPRESSIONOPTION_MAXIMUM:
+                compression_method=8;
+                bit_flag|=1<<1;
+                break;
+            case OPC_COMPRESSIONOPTION_FAST:
+                compression_method=8;
+                bit_flag|=2<<1;
+                break;
+            case OPC_COMPRESSIONOPTION_SUPERFAST:
+                compression_method=8;
+                bit_flag|=3<<1;
+                break;
+            }
+            ret->stream=opcZipCreateOutputStream(container->storage, first_segment, name, rels_segment, 0, 0, compression_method, bit_flag);
+            ret->partName=name;
+            ret->rels_segment=rels_segment;
+            if (NULL==ret->stream) {
+                xmlFree(ret); ret=NULL; // error
+            }
+        }
+    }
+    return ret;
+}
+
+opcContainerOutputStream* opcContainerCreateOutputStream(opcContainer *container, const xmlChar *name, opcCompressionOption_t compression_option) {
+    return opcContainerCreateOutputStreamEx(container, name, OPC_FALSE, compression_option);
+}
+
+opc_uint32_t opcContainerWriteOutputStream(opcContainerOutputStream* stream, const opc_uint8_t *buffer, opc_uint32_t buffer_len) {
+    return opcZipWriteOutputStream(stream->container->storage, stream->stream, buffer, buffer_len);
+}
+
+opc_error_t opcContainerCloseOutputStream(opcContainerOutputStream* stream) {
+    opc_error_t ret=OPC_ERROR_MEMORY;
+    opc_uint32_t *first_segment=NULL;
+    opc_uint32_t *last_segment=NULL;
+    opcContainerGetOutputPartSegment(stream->container, stream->partName, stream->rels_segment, &first_segment, &last_segment);
+    OPC_ASSERT(NULL!=first_segment);
+    if (NULL!=first_segment) {
+        ret=opcZipCloseOutputStream(stream->container->storage, stream->stream, first_segment);
+        if (NULL!=last_segment) {
+            *last_segment=*first_segment; 
+        }
+        xmlFree(stream);
+    }
+    return ret;
+}
+
+static opc_error_t opcContainerInit(opcContainer *c, opcContainerOpenMode mode, void *userContext) {
+    opc_bzero_mem(c, sizeof(*c));
+    c->content_types_segment_id=-1;
+    c->rels_segment_id=-1;
+    c->mode=mode;
+    c->userContext=userContext;
+    return OPC_ERROR_NONE;
+}
+
+static opcContainer *opcContainerLoadFromZip(opcContainer *c) {
+    OPC_ASSERT(NULL==c->storage); // loaded twice??
+    c->storage=opcZipCreate(&c->io);
+    if (NULL!=c->storage) {
+        if (OPC_ERROR_NONE==opcZipLoader(&c->io, c, opcContainerZipLoaderLoadSegment)) {
+            // successfull loaded!
+            OPC_ENSURE(OPC_ERROR_NONE==opcZipGC(c->storage));
+            if (-1!=c->content_types_segment_id) {
+                mceTextReader_t reader;
+                if (OPC_ERROR_NONE==opcXmlReaderOpenEx(c, &reader, OPC_SEGMENT_CONTENTTYPES, OPC_FALSE, NULL, NULL, 0)) {
+                    static const char ns[]="http://schemas.openxmlformats.org/package/2006/content-types";
+                    mce_start_document(&reader) {
+                        mce_start_element(&reader, _X(ns), _X("Types")) {
+                            mce_skip_attributes(&reader);
+                            mce_start_children(&reader) {
+                                mce_start_element(&reader, NULL, _X("Default")) {
+                                    const xmlChar *ext=NULL;
+                                    const xmlChar *type=NULL;
+                                    mce_start_attributes(&reader) {
+                                        mce_start_attribute(&reader, NULL, _X("Extension")) {
+                                            ext=xmlTextReaderConstValue(reader.reader);
+                                        } mce_end_attribute(&reader);
+                                        mce_start_attribute(&reader, NULL, _X("ContentType")) {
+                                            type=xmlTextReaderConstValue(reader.reader);
+                                        } mce_end_attribute(&reader);
+                                    } mce_end_attributes(&reader);
+                                    mce_error_guard_start(&reader) {
+                                        mce_error(&reader, NULL==ext || ext[0]==0, MCE_ERROR_VALIDATION, "Missing @Extension attribute!");
+                                        mce_error(&reader, NULL==type || type[0]==0, MCE_ERROR_VALIDATION, "Missing @ContentType attribute!");
+                                        opcContainerType *ct=insertType(c, type, OPC_TRUE);
+                                        mce_error(&reader, NULL==ct, MCE_ERROR_MEMORY, NULL);
+                                        opcContainerExtension *ce=opcContainerInsertExtension(c, ext, OPC_TRUE);
+                                        mce_error(&reader, NULL==ce, MCE_ERROR_MEMORY, NULL);
+                                        mce_errorf(&reader, NULL!=ce->type && 0!=xmlStrcmp(ce->type, type), MCE_ERROR_VALIDATION, "Extension \"%s\" is mapped to type \"%s\" as well as \"%s\"", ext, type, ce->type);
+                                        ce->type=ct->type;
+                                    } mce_error_guard_end(&reader);
+                                    mce_skip_children(&reader);
+                                } mce_end_element(&reader);
+                                mce_start_element(&reader, NULL, _X("Override")) {
+                                    const xmlChar *name=NULL;
+                                    const xmlChar *type=NULL;
+                                    mce_start_attributes(&reader) {
+                                        mce_start_attribute(&reader, NULL, _X("PartName")) {
+                                            name=xmlTextReaderConstValue(reader.reader);
+                                        } mce_end_attribute(&reader);
+                                        mce_start_attribute(&reader, NULL, _X("ContentType")) {
+                                            type=xmlTextReaderConstValue(reader.reader);
+                                        } mce_end_attribute(&reader);
+                                    } mce_end_attributes(&reader);
+                                    mce_error_guard_start(&reader) {
+                                        mce_error(&reader, NULL==name, MCE_ERROR_XML, "Attribute @PartName not given!");
+                                        mce_error(&reader, NULL==type, MCE_ERROR_XML, "Attribute @ContentType not given!");
+                                        opcContainerType*ct=insertType(c, type, OPC_TRUE);
+                                        mce_error(&reader, NULL==ct, MCE_ERROR_MEMORY, NULL);
+                                        mce_error_strictf(&reader, '/'!=name[0], MCE_ERROR_MEMORY, "Part %s MUST start with a '/'", name);
+                                        opcContainerPart *part=opcContainerInsertPart(c, (name[0]=='/'?name+1:name), OPC_FALSE);
+                                        mce_error_strictf(&reader, NULL==part, MCE_ERROR_MEMORY, "Part %s does not exist.", name);
+                                        if (NULL!=part) {
+                                            part->type=ct->type;
+                                        }
+                                    } mce_error_guard_end(&reader);
+                                    mce_skip_children(&reader);
+                                } mce_end_element(&reader);
+                                mce_start_text(&reader) {
+                                    //@TODO ensure whitespaces...
+                                } mce_end_text(&reader);
+                            } mce_end_children(&reader);
+                        } mce_end_element(&reader);
+                    } mce_end_document(&reader);
+                    OPC_ENSURE(0==mceTextReaderCleanup(&reader));
+                }
+            }
+            if (NULL!=c && -1!=c->rels_segment_id) {
+                opcConstainerParseRels(c, OPC_SEGMENT_ROOTRELS, &c->relation_array, &c->relation_items);
+            }
+            for(opc_uint32_t i=0;NULL!=c && i<c->part_items;i++) {
+                opcContainerPart *part=&c->part_array[i];
+                if (-1!=part->rel_segment_id) {
+                    opcConstainerParseRels(c, part->name, &part->relation_array, &part->relation_items);
+                }
+            }
+        } else {
+            opcFileCleanupIO(&c->io); // error loading
+            opcZipClose(c->storage, NULL);
+            xmlFree(c); c=NULL;
+        }
+    } else {
+        opcFileCleanupIO(&c->io); // error creating zip
+        xmlFree(c); c=NULL;
+    }
+    return c;
+}
+
+static opc_uint32_t opcContainerGenerateFileFlags(opcContainerOpenMode mode) {
+    opc_uint32_t flags=(OPC_OPEN_READ_ONLY!=mode?OPC_FILE_WRITE | OPC_FILE_READ:OPC_FILE_READ);
+    if (OPC_OPEN_WRITE_ONLY==mode) flags=flags | OPC_FILE_TRUNC;
+    return flags;
+}
+
+opcContainer* opcContainerOpen(const xmlChar *fileName, 
+                               opcContainerOpenMode mode, 
+                               void *userContext, 
+                               const xmlChar *destName) {
+    opcContainer*c=(opcContainer*)xmlMalloc(sizeof(opcContainer));
+    if (NULL!=c) {
+        OPC_ENSURE(OPC_ERROR_NONE==opcContainerInit(c, mode, userContext));
+        if (OPC_ERROR_NONE==opcFileInitIOFile(&c->io, fileName, opcContainerGenerateFileFlags(mode))) {
+            c=opcContainerLoadFromZip(c);
+        } else {
+            xmlFree(c); c=NULL; // error init io
+        }
+    }
+    return c;
+}
+
+opcContainer* opcContainerOpenMem(const opc_uint8_t *data, opc_uint32_t data_len,
+                                  opcContainerOpenMode mode, 
+                                  void *userContext) {
+    opcContainer*c=(opcContainer*)xmlMalloc(sizeof(opcContainer));
+    if (NULL!=c) {
+        OPC_ENSURE(OPC_ERROR_NONE==opcContainerInit(c, mode, userContext));
+        if (OPC_ERROR_NONE==opcFileInitIOMemory(&c->io, data, data_len, opcContainerGenerateFileFlags(mode))) {
+            c=opcContainerLoadFromZip(c);
+        } else {
+            xmlFree(c); c=NULL; // error init io
+        }
+    }
+    return c;
+}
+
+opcContainer* opcContainerOpenIO(opcFileReadCallback *ioread,
+                                 opcFileWriteCallback *iowrite,
+                                 opcFileCloseCallback *ioclose,
+                                 opcFileSeekCallback *ioseek,
+                                 opcFileTrimCallback *iotrim,
+                                 opcFileFlushCallback *ioflush,
+                                 void *iocontext,
+                                 pofs_t file_size,
+                                 opcContainerOpenMode mode, 
+                                 void *userContext) {
+    opcContainer*c=(opcContainer*)xmlMalloc(sizeof(opcContainer));
+    if (NULL!=c) {
+        OPC_ENSURE(OPC_ERROR_NONE==opcContainerInit(c, mode, userContext));
+        if (OPC_ERROR_NONE==opcFileInitIO(&c->io, ioread, iowrite, ioclose, ioseek, iotrim, ioflush, iocontext, file_size, opcContainerGenerateFileFlags(mode))) {
+            c=opcContainerLoadFromZip(c);
+        } else {
+            xmlFree(c); c=NULL; // error init io
+        }
+    }
+    return c;
+}
+
+
+static void opcContainerWriteUtf8Raw(opcContainerOutputStream *out, const xmlChar *str) {
+    opc_uint32_t str_len=xmlStrlen(str);
+    OPC_ENSURE(str_len==opcContainerWriteOutputStream(out, str, str_len));
+}
+
+static void opcContainerWriteUtf8(opcContainerOutputStream *out, const xmlChar *str) {
+    for(;0!=*str; str++) {
+        switch(*str) {
+        case '"':
+            OPC_ENSURE(6==opcContainerWriteOutputStream(out, _X("&quot;"), 6));
+            break;
+        case '\'':
+            OPC_ENSURE(6==opcContainerWriteOutputStream(out, _X("&apos;"), 6));
+            break;
+        case '&':
+            OPC_ENSURE(5==opcContainerWriteOutputStream(out, _X("&amp;"), 5));
+            break;
+        case '<':
+            OPC_ENSURE(4==opcContainerWriteOutputStream(out, _X("&lt;"), 4));
+            break;
+        case '>':
+            OPC_ENSURE(4==opcContainerWriteOutputStream(out, _X("&gt;"), 4));
+            break;
+        default:
+            OPC_ENSURE(1==opcContainerWriteOutputStream(out, str, 1));
+            break;
+        }
+    }
+}
+
+
+static void opcContainerWriteContentTypes(opcContainer *c) {
+    opcContainerOutputStream *out=opcContainerCreateOutputStreamEx(c, OPC_SEGMENT_CONTENTTYPES, OPC_FALSE, OPC_COMPRESSIONOPTION_NORMAL);
+    if (NULL!=out) {
+        opcContainerWriteUtf8Raw(out, _X("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">"));
+        for(opc_uint32_t i=0;i<c->extension_items;i++) {
+            opcContainerWriteUtf8Raw(out, _X("<Default Extension=\""));
+            opcContainerWriteUtf8(out, c->extension_array[i].extension);
+            opcContainerWriteUtf8Raw(out, _X("\" ContentType=\""));
+            opcContainerWriteUtf8(out, c->extension_array[i].type);
+            opcContainerWriteUtf8Raw(out, _X("\"/>"));
+        }
+        for(opc_uint32_t i=0;i<c->part_items;i++) {
+            if (NULL!=c->part_array[i].type) {
+                opcContainerWriteUtf8Raw(out, _X("<Override PartName=\"/"));
+                opcContainerWriteUtf8(out, c->part_array[i].name);
+                opcContainerWriteUtf8Raw(out, _X("\" ContentType=\""));
+                opcContainerWriteUtf8(out, c->part_array[i].type);
+                opcContainerWriteUtf8Raw(out, _X("\"/>"));
+            }
+        }
+        opcContainerWriteUtf8Raw(out, _X("</Types>"));
+        opcContainerCloseOutputStream(out);
+    }
+}
+
+static void opcHelperCalcRelPath(xmlChar *rel_path, opc_uint32_t rel_path_max, const xmlChar *base, const xmlChar *path) {
+    opc_uint32_t base_pos=0;
+    opc_uint32_t path_pos=0;
+    opc_uint32_t rel_pos=0;
+
+    while(0!=base[base_pos]) {
+        opc_uint32_t base_next=base_pos; while(0!=base[base_next] && '/'!=base[base_next]) base_next++;
+        opc_uint32_t path_next=path_pos;  while(0!=base[path_next] && '/'!=base[path_next]) path_next++;
+        if ('/'==base[base_next]) {
+            if (base_next==path_next && 0==xmlStrncmp(base+base_pos, path+path_pos, base_next-base_pos)) {
+                base_pos=base_next+1;
+                path_pos=path_next+1;
+            } else {
+                base_pos=base_next+1;
+                strncpy((char *)(rel_path+rel_pos), "../", rel_path_max-rel_pos);
+                rel_pos+=3;
+            }
+        } else {
+            OPC_ASSERT(0==base[base_next]);
+            base_pos=base_next;
+            OPC_ASSERT(0==base[base_pos]);
+        }
+    }
+    strncpy((char *)(rel_path+rel_pos), (const char *)(path+path_pos), rel_path_max-rel_pos);
+#if 0 // for debugging only...
+    xmlChar helper[OPC_MAX_PATH];
+    opc_container_normalize_part_to_helper_buffer(helper, sizeof(helper), base, rel_path);
+    OPC_ASSERT(0==xmlStrcmp(path, helper));
+#endif
+}
+
+static void opcContainerWriteRels(opcContainer *c, const xmlChar *part_name, opcContainerRelation *relation_array, opc_uint32_t relation_items) {
+    opcContainerOutputStream *out=opcContainerCreateOutputStreamEx(c, part_name, OPC_TRUE, OPC_COMPRESSIONOPTION_NORMAL);
+    if (NULL!=out) {
+        opcContainerWriteUtf8Raw(out, _X("<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">"));
+        for(opc_uint32_t i=0;i<relation_items;i++) {
+            opcContainerWriteUtf8Raw(out, _X("<Relationship Id=\""));
+            opcContainerWriteUtf8(out, c->relprefix_array[OPC_CONTAINER_RELID_PREFIX(relation_array[i].relation_id)].prefix);
+            if (OPC_CONTAINER_RELID_COUNTER_NONE!=OPC_CONTAINER_RELID_COUNTER(relation_array[i].relation_id)) {
+                char buf[20];
+                snprintf(buf, sizeof(buf), "%i", OPC_CONTAINER_RELID_COUNTER(relation_array[i].relation_id));
+                opcContainerWriteUtf8Raw(out, _X(buf));
+            }
+            opcContainerWriteUtf8Raw(out, _X("\" Type=\""));
+            opcContainerWriteUtf8(out, relation_array[i].relation_type);
+            if (0==relation_array[i].target_mode) {
+                opcContainerWriteUtf8Raw(out, _X("\" Target=\""));
+                xmlChar rel_path[OPC_MAX_PATH];
+                opcHelperCalcRelPath(rel_path, sizeof(rel_path), part_name, relation_array[i].target_ptr);
+                opcContainerWriteUtf8(out, rel_path);
+            } else {
+                OPC_ASSERT(1==relation_array[i].target_mode);
+                opcContainerWriteUtf8Raw(out, _X("\" TargetMode=\"External\" Target=\""));
+                opcContainerWriteUtf8(out, relation_array[i].target_ptr);
+            }
+            opcContainerWriteUtf8Raw(out, _X("\"/>"));
+        }
+        opcContainerWriteUtf8Raw(out, _X("</Relationships>"));
+        opcContainerCloseOutputStream(out);
+    }
+}
+
+
+static void opcContainerWriteAllRels(opcContainer *c) {
+    if (c->relation_items>0) {
+        opcContainerWriteRels(c, OPC_SEGMENT_ROOTRELS, c->relation_array, c->relation_items);
+    }
+    for(opc_uint32_t i=0;i<c->part_items;i++) {
+        if (c->part_array[i].relation_items>0) {
+            opcContainerWriteRels(c, c->part_array[i].name, c->part_array[i].relation_array, c->part_array[i].relation_items);
+        }
+    }
+}
+
+opc_error_t opcContainerCommit(opcContainer *c, opc_bool_t trim) {
+    opc_error_t ret=OPC_ERROR_NONE;
+    if (OPC_OPEN_READ_ONLY!=c->mode) {
+        opcContainerWriteContentTypes(c);
+        opcContainerWriteAllRels(c);
+        ret=opcZipCommit(c->storage, trim);
+    }
+    return ret;
+}
+
+opc_error_t opcContainerClose(opcContainer *c, opcContainerCloseMode mode) {
+    opc_bool_t trim=(mode!=OPC_CLOSE_NOW);
+    opc_error_t ret=opcContainerCommit(c, trim);
+    opcZipClose(c->storage, NULL); c->storage=NULL;
+    opcContainerFree(c);
+    return ret;
+}
+
+opc_bool_t opcContainerDeletePartEx(opcContainer *container, const xmlChar *partName, opc_bool_t rels_segment) {
+    opc_bool_t ret=OPC_FALSE;
+    if (OPC_SEGMENT_CONTENTTYPES==partName) {
+        OPC_ASSERT(!rels_segment);
+        ret=opcZipSegmentDelete(container->storage, &container->content_types_segment_id, NULL, NULL);
+    } else if (OPC_SEGMENT_ROOTRELS==partName) {
+        OPC_ASSERT(rels_segment);
+        ret=opcZipSegmentDelete(container->storage, &container->rels_segment_id, NULL, NULL);
+    } else {
+        opcContainerPart *part=opcContainerInsertPart(container, partName, OPC_FALSE);
+        if (NULL!=part) {
+            if (rels_segment) {
+                ret=opcZipSegmentDelete(container->storage, &part->rel_segment_id, NULL, NULL);
+            } else {
+                ret=opcZipSegmentDelete(container->storage, &part->first_segment_id, &part->last_segment_id, NULL);
+            }
+        }
+    }
+    return ret;
+}
+
+
+const xmlChar *opcContentTypeFirst(opcContainer *container) {
+    if (container->type_items>0) {
+        return container->type_array[0].type;
+    } else {
+        return NULL;
+    }
+}
+
+const xmlChar *opcContentTypeNext(opcContainer *container, const xmlChar *type) {
+    opcContainerType *t=insertType(container, type, OPC_FALSE);
+    if (NULL!=t && t>=container->type_array && t+1<container->type_array+container->type_items) {
+        return (t+1)->type;
+    } else {
+        return NULL;
+    }
+}
+
+const xmlChar *opcExtensionFirst(opcContainer *container) {
+    if (container->extension_items>0) {
+        return container->extension_array[0].extension;
+    } else {
+        return NULL;
+    }
+}
+
+
+const xmlChar *opcExtensionNext(opcContainer *container, const xmlChar *ext) {
+    opcContainerExtension *e=opcContainerInsertExtension(container, ext, OPC_FALSE);
+    if (NULL!=e && e>=container->extension_array && e+1<container->extension_array+container->extension_items) {
+        return (e+1)->extension;
+    } else {
+        return NULL;
+    }
+}
+
+const xmlChar *opcExtensionGetType(opcContainer *container, const xmlChar *ext) {
+    opcContainerExtension *e=opcContainerInsertExtension(container, ext, OPC_FALSE);
+    if (NULL!=e && e>=container->extension_array && e<container->extension_array+container->extension_items) {
+        return e->type;
+    } else {
+        return NULL;
+    }
+}
+
+const xmlChar *opcExtensionRegister(opcContainer *container, const xmlChar *ext, const xmlChar *type) {
+    opcContainerType *_type=insertType(container, type, OPC_TRUE);
+    opcContainerExtension *_ext=opcContainerInsertExtension(container, ext, OPC_TRUE);
+    if (_ext!=NULL && _type!=NULL) {
+        OPC_ASSERT(NULL==_ext->type);
+        _ext->type=_type->type;
+        return _ext->extension;
+    } else {
+        return NULL;
+    }
+}
+
+opc_uint32_t opcRelationAdd(opcContainer *container, opcPart src, const xmlChar *rid, opcPart dest, const xmlChar *type) {
+    opc_uint32_t ret=-1;
+    opcContainerRelation **relation_array=NULL;
+    opc_uint32_t *relation_items=NULL;
+    if (OPC_PART_INVALID==src) {
+        relation_array=&container->relation_array;
+        relation_items=&container->relation_items;
+    } else {
+        opcContainerPart *src_part=opcContainerInsertPart(container, src, OPC_FALSE);
+        if (NULL!=src_part) {
+            relation_array=&src_part->relation_array;
+            relation_items=&src_part->relation_items;
+        }
+    }
+    opcContainerPart *dest_part=opcContainerInsertPart(container, dest, OPC_FALSE);
+    char buf[OPC_MAX_PATH];
+    strncpy(buf, (const char *)rid, OPC_MAX_PATH);
+    opc_uint32_t counter=-1;
+    opc_uint32_t id_len=splitRelPrefix(container, _X(buf), &counter);
+    buf[id_len]=0;
+    opc_uint32_t rel_id=createRelId(container, _X(buf), counter);
+
+    if (NULL!=relation_array && NULL!=dest_part) {
+        opcContainerRelationType *rel_type=(NULL!=type?opcContainerInsertRelationType(container, type, OPC_TRUE):NULL);
+        opcContainerRelation *rel=opcContainerInsertRelation(relation_array, relation_items, rel_id, (NULL!=rel_type?rel_type->type:NULL), 0, dest_part->name);
+        if (NULL!=rel) {
+            OPC_ASSERT(rel>=*relation_array && rel<*relation_array+*relation_items);
+            OPC_ASSERT(0==rel->target_mode);
+            ret=rel_id;
+        }
+    }
+    return ret;
+}
+
+opc_uint32_t opcRelationAddExternal(opcContainer *container, opcPart src, const xmlChar *rid, const xmlChar *target, const xmlChar *type) {
+    opc_uint32_t ret=-1;
+    opcContainerRelation **relation_array=NULL;
+    opc_uint32_t *relation_items=NULL;
+    if (OPC_PART_INVALID==src) {
+        relation_array=&container->relation_array;
+        relation_items=&container->relation_items;
+    } else {
+        opcContainerPart *src_part=opcContainerInsertPart(container, src, OPC_FALSE);
+        if (NULL!=src_part) {
+            relation_array=&src_part->relation_array;
+            relation_items=&src_part->relation_items;
+        }
+    }
+    opcContainerExternalRelation *_target=insertExternalRelation(container, target, OPC_TRUE);
+    char buf[OPC_MAX_PATH];
+    strncpy(buf, (const char *)rid, OPC_MAX_PATH);
+    opc_uint32_t counter=-1;
+    opc_uint32_t id_len=splitRelPrefix(container, _X(buf), &counter);
+    buf[id_len]=0;
+    opc_uint32_t rel_id=createRelId(container, _X(buf), counter);
+
+    if (NULL!=relation_array && NULL!=_target) {
+        opcContainerRelationType *rel_type=(NULL!=type?opcContainerInsertRelationType(container, type, OPC_TRUE):NULL);
+        opcContainerRelation *rel=opcContainerInsertRelation(relation_array, relation_items, rel_id, (NULL!=rel_type?rel_type->type:NULL), 0, _target->target);
+        if (NULL!=rel) {
+            OPC_ASSERT(rel>=*relation_array && rel<*relation_array+*relation_items);
+            rel->target_mode=1;
+            ret=rel_id;
+        }
+    }
+    return ret;
+}
+
+static inline int qname_level_cmp_fct(const void *key, opc_uint32_t v, const void *array_, opc_uint32_t item) {
+    opcQNameLevel_t *q1=(opcQNameLevel_t*)key;
+    opcQNameLevel_t *q2=&((opcQNameLevel_t*)array_)[item];
+    int const ns_cmp=(NULL==q1->ns?(NULL==q2->ns?0:-1):(NULL==q2->ns?+1:xmlStrcmp(q1->ns, q2->ns)));
+    return (0==ns_cmp?xmlStrcmp(q1->ln, q2->ln):ns_cmp);
+}
+
+
+opc_error_t opcQNameLevelAdd(opcQNameLevel_t **list_array, opc_uint32_t *list_items, opcQNameLevel_t *item) {
+    opc_uint32_t i=0;
+    opc_error_t ret=OPC_ERROR_NONE;
+    if (!findItem(*list_array, *list_items, item, 0, qname_level_cmp_fct, &i)) {
+        if (NULL!=ensureItem((void**)list_array, *list_items, sizeof(opcQNameLevel_t))) {
+            ensureGap(*list_array, *list_items, i);
+            (*list_array)[i]=*item;
+        } else {
+            ret=OPC_ERROR_MEMORY;
+        }
+    }
+    return ret;
+}
+
+opcQNameLevel_t* opcQNameLevelLookup(opcQNameLevel_t *list_array, opc_uint32_t list_items, const xmlChar *ns, const xmlChar *ln) {
+    opcQNameLevel_t item;
+    item.level=0;
+    item.ln=(xmlChar *)ln;
+    item.ns=ns;
+    opc_uint32_t i=0;
+    opc_bool_t ret=NULL!=list_array && list_items>0 && findItem(list_array, list_items, &item, 0, qname_level_cmp_fct, &i);
+    return (ret?list_array+i:NULL);
+}
+
+opc_error_t opcQNameLevelCleanup(opcQNameLevel_t *list_array, opc_uint32_t *list_items, opc_uint32_t level, opc_uint32_t *max_level) {
+    opc_uint32_t i=0;
+    for(opc_uint32_t j=0;j<*list_items;j++) {
+        if (list_array[j].level>=level) {
+            OPC_ASSERT(list_array[j].level==level); // cleanup should be called for every level...
+            if (NULL!=list_array[j].ln) xmlFree(list_array[j].ln);
+            // list_array[j].ns is managed by ther parser...
+        } else {
+            if (NULL!=max_level && list_array[j].level>*max_level) *max_level=list_array[j].level;
+            list_array[i++]=list_array[j];
+        }
+    }
+    *list_items=i;
+    return OPC_ERROR_NONE;
+}
+
+opc_error_t opcQNameLevelPush(opcQNameLevel_t **list_array, opc_uint32_t *list_items, opcQNameLevel_t *item) {
+    opc_error_t ret=OPC_ERROR_NONE;
+    if (NULL!=(ensureItem((void**)list_array, *list_items, sizeof(opcQNameLevel_t)))) {
+        (*list_array)[*list_items]=*item;
+        (*list_items)++;
+    } else {
+        ret=OPC_ERROR_MEMORY;
+    }
+    return ret;
+}
+
+opc_bool_t opcQNameLevelPopIfMatch(opcQNameLevel_t *list_array, opc_uint32_t *list_items, const xmlChar *ns, const xmlChar *ln, opc_uint32_t level) {
+    opc_bool_t ret=*list_items>0 && list_array[(*list_items)-1].level==level;
+    if (ret) {
+        OPC_ASSERT(0==xmlStrcmp(list_array[(*list_items)-1].ln, ln) && 0==xmlStrcmp(list_array[(*list_items)-1].ns, ns));
+        OPC_ASSERT(*list_items>0);
+        if (NULL!=list_array[(*list_items)-1].ln) xmlFree(list_array[(*list_items)-1].ln);
+        (*list_items)--;
+    }
+    return ret;
+}
+
+
+const xmlChar *opcRelationTypeFirst(opcContainer *container) {
+    if (container->relationtype_items>0) {
+        return container->relationtype_array[0].type;
+    } else {
+        return NULL;
+    }
+}
+
+const xmlChar *opcRelationTypeNext(opcContainer *container, const xmlChar *type) {
+    opcContainerRelationType* t=opcContainerInsertRelationType(container, type, OPC_FALSE);
+    if (NULL!=t && t>=container->relationtype_array && t+1<container->relationtype_array+container->relationtype_items) {
+        return (t+1)->type;
+    } else {
+        return NULL;
+    }
+}
+
+const xmlChar *opcExternalTargetFirst(opcContainer *container) {
+    if (container->externalrelation_items>0) {
+        return container->externalrelation_array[0].target;
+    } else {
+        return NULL;
+    }
+}
+
+const xmlChar *opcExternalTargetNext(opcContainer *container, const xmlChar *target) {
+    opcContainerExternalRelation*e=insertExternalRelation(container, target, OPC_FALSE);
+    if (NULL!=e && e>=container->externalrelation_array && e+1<container->externalrelation_array+container->externalrelation_items) {
+        return (e+1)->target;
+    } else {
+        return NULL;
+    }
+}

+ 300 - 0
opc/container.h

@@ -0,0 +1,300 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/container.h
+
+ The container.h module has the fundamental methods for dealing with ZIP-based OPC container. 
+ 
+ OPC container can be opened in READ-ONLY mode, WRITE-ONLY mode, READ/WRITE mode, TEMPLATE mode and TRANSITION mode. 
+ The most notable mode is the READ/WRITE mode, which gives you concurrent stream-based READ and WRITE access to a 
+ single ZIP-based OPC container. This is achieved without the use of temporary files by taking advantage of the 
+ OPC specific “interleave” mode. \see http://standards.iso.org/ittf/PubliclyAvailableStandards/c051459_ISOIEC_29500-2_2008(E).zip
+ 
+ The TEMPLATE mode allows very fast customized "cloning" of ZIP-based OPC container by using "RAW access" to the ZIP streams. 
+ The TRANSITION mode is a special version of the TEMPLATE mode, which allows transition-based READ/WRITE access to the 
+ ZIP-based OPC container using a temporary file.
+ 
+ */
+#include <opc/config.h>
+#include <opc/file.h>
+
+#ifndef OPC_CONTAINER_H
+#define OPC_CONTAINER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+    /**
+     Handle to an OPC container created by \ref opcContainerOpen.
+     \see opcContainerOpen.
+     */
+    typedef struct OPC_CONTAINER_STRUCT opcContainer;
+    
+    /**
+     Modes for opcContainerOpen();
+     \see opcContainerOpen
+     */
+    typedef enum {
+        /**
+         Opens the OPC container denoted by \a fileName in READ-ONLY mode. The \a destName parameter must be \a NULL.
+         \hideinitializer
+         */
+        OPC_OPEN_READ_ONLY=0, 
+        /**
+         Opens the OPC container denoted by \a fileName in WRITE-ONLY mode. The \a destName parameter must be \a NULL.
+         \hideinitializer
+         */
+        OPC_OPEN_WRITE_ONLY=1,
+        /**
+         Opens the OPC container denoted by \a fileName in READ/WRITE mode. The \a destName parameter must be \a NULL.
+         \hideinitializer
+         */
+        OPC_OPEN_READ_WRITE=2,
+        /**
+         This mode will open the container denoted by \a fileName in READ-ONLY mode and the container denoted by 
+         \a destName in write-only mode. Any modifications will be written to the container denoted by \a destName 
+         and the unmodified streams from \a fileName will be written to \a destName on closing.
+         \warning Currently not implemented.
+         \hideinitializer
+         */
+        OPC_OPEN_TEMPLATE=3,
+        /**
+         Like the OPC_OPEN_TEMPLATE mode, but the \a destName will be renamed to the \a fileName on closing. If \a destName 
+         is \a NULL, then the name of the temporary file will be generated automatically.
+         \warning Currently not implemented.
+         \hideinitializer
+         */
+        OPC_OPEN_TRANSITION=4
+    } opcContainerOpenMode; 
+    
+    /** Modes for opcContainerClose.
+     \see opcContainerClose.
+     */
+    typedef enum {
+        /**
+         Close the OPC container without any further postprocessing.
+         \hideinitializer
+         */
+        OPC_CLOSE_NOW = 0,
+        /**
+         Close the OPC container and trim the file by removing unused fragments like e.g. 
+         deleted parts.
+         \hideinitializer
+         */
+        OPC_CLOSE_TRIM = 1,
+        /**
+         Close the OPC container like in \a OPC_CLOSE_TRIM mode, but additionally remove any 
+         "interleaved" parts by reordering them.
+         \warning Currently not implemented. Same semantic as OPC_CLOSE_TRIM.       
+         \hideinitializer
+         */
+        OPC_CLOSE_DEFRAG = 2
+    } opcContainerCloseMode;
+    
+    /**
+     Opens a ZIP-based OPC container.
+     @param[in] fileName. For more details see \ref opcContainerOpenMode.
+     @param[in] mode. For more details see \ref opcContainerOpenMode.
+     @param[in] userContext. Will not be modified by libopc. Can be used to e.g. store the "this" pointer for C++ bindings.
+     @param[in] destName. For more details see \ref opcContainerOpenMode.
+     @return \a NULL if failed. 
+     \see opcContainerOpenMode
+     \see opcContainerDump
+     */
+    opcContainer* opcContainerOpen(const xmlChar *fileName, 
+                                   opcContainerOpenMode mode, 
+                                   void *userContext, 
+                                   const xmlChar *destName);
+
+    /**
+     Opens a ZIP-based OPC container from memory.
+     @param[in] data. 
+     @param[in] data_len.
+     @param[in] userContext. Will not be modified by libopc. Can be used to e.g. store the "this" pointer for C++ bindings.
+     @param[in] mode. For more details see \ref opcContainerOpenMode.
+     @return \a NULL if failed. 
+     */
+    opcContainer* opcContainerOpenMem(const opc_uint8_t *data, opc_uint32_t data_len,
+                                      opcContainerOpenMode mode, 
+                                      void *userContext);
+
+    /**
+     Opens a ZIP-based OPC container from memory.
+     @param[in] ioread. 
+     @param[in] iowrite. 
+     @param[in] ioclose. 
+     @param[in] ioseek. 
+     @param[in] iotrim. 
+     @param[in] ioflush. 
+     @param[in] iocontext. 
+     @param[in] file_size. 
+     @param[in] userContext. Will not be modified by libopc. Can be used to e.g. store the "this" pointer for C++ bindings.
+     @param[in] mode. For more details see \ref opcContainerOpenMode.
+     @return \a NULL if failed. 
+     */
+    opcContainer* opcContainerOpenIO(opcFileReadCallback *ioread,
+                                     opcFileWriteCallback *iowrite,
+                                     opcFileCloseCallback *ioclose,
+                                     opcFileSeekCallback *ioseek,
+                                     opcFileTrimCallback *iotrim,
+                                     opcFileFlushCallback *ioflush,
+                                     void *iocontext,
+                                     pofs_t file_size,
+                                     opcContainerOpenMode mode, 
+                                     void *userContext);
+    
+    /**
+     Close an OPC container.
+     @param[in] c. \ref opcContainer openered by \ref opcContainerOpen.
+     @param[in] mode. For more information see \ref opcContainerCloseMode.
+     @return Non-zero if successful.
+     \see opcContainerOpen
+     \see opcContainerCloseMode
+     */
+    opc_error_t opcContainerClose(opcContainer *c, opcContainerCloseMode mode);
+    
+    /**
+     Returns the unmodified user context passed to \ref opcContainerOpen.
+     \see opcContainerOpen
+     */
+    void *opcContainerGetUserContext(opcContainer *c);
+    
+    /**
+     List all types, relations and parts of the container \a c to \a out.
+     \par Sample:
+     \include opc_dump.c
+     */
+    opc_error_t opcContainerDump(opcContainer *c, FILE *out);
+    
+    /**
+     Exports the OPC container to "Flat OPC" (http://blogs.msdn.com/b/ericwhite/archive/2008/09/29/the-flat-opc-format.aspx).
+     The flat versions of an OPC file are very important when dealing with e.g XSL(T)-based or Javascript-based transformations.
+     \see opcContainerFlatImport.
+     \todo Implementation needed.
+     */
+    int opcContainerFlatExport(opcContainer *c, const xmlChar *fileName);
+    
+    /**
+     Imports the flat version of an OPC container. 
+     \see opcContainerFlatExport.
+     \todo Implementation needed.
+     */
+    int opcContainerFlatImport(opcContainer *c, const xmlChar *fileName);
+    
+    /**
+     Iterate all types.
+     \code
+     for(xmlChar *type=opcContentTypeFirst(c);
+         NULL!=type;
+         type=opcContentTypeNext(c, type)) {
+        printf("%s\n", type);
+     }
+     \endcode
+    */
+    const xmlChar *opcContentTypeFirst(opcContainer *container);
+    
+    /**
+     \see opcContentTypeNext()
+    */
+    const xmlChar *opcContentTypeNext(opcContainer *container, const xmlChar *type);
+
+    /**
+     Iterate extensions.
+     \code
+     for(const xmlChar *ext=opcExtensionFirst(c);
+         NULL!=ext;
+         ext=opcExtensionNext(ext)) {
+        printf("%s\n", ext);
+     }
+     \endcode
+    */
+    const xmlChar *opcExtensionFirst(opcContainer *container);
+    
+    /**
+     \see opcExtensionFirst()
+     */
+    const xmlChar *opcExtensionNext(opcContainer *container, const xmlChar *ext);
+    
+    /**
+     Get registered type for extension.
+     \see opcExtensionRegister()
+     */
+    const xmlChar *opcExtensionGetType(opcContainer *container, const xmlChar *ext);
+
+    /**
+     Register a mime-type and and extension.
+     \see opcExtensionGetType()
+     */
+    const xmlChar *opcExtensionRegister(opcContainer *container, const xmlChar *ext, const xmlChar *type);
+
+
+    /**
+     Iterator through all relation types of the container:
+     \code
+     for(xmlChar *type=opcRelationTypeFirst(c);
+         NULL!=type;
+         type=opcRelationTypeNext(c, type)) {
+        printf("%s\n", type);
+     }
+     \endcode
+     */
+    const xmlChar *opcRelationTypeFirst(opcContainer *container);
+
+    /**
+     \see opcRelationTypeFirst()
+    */
+    const xmlChar *opcRelationTypeNext(opcContainer *container, const xmlChar *type);
+
+
+    /**
+     Iterator through all relation types of the container:
+     \code
+     for(xmlChar *target=opcExternalTargetFirst(c);
+         NULL!=target;
+         type=opcExternalTargetNext(c, target)) {
+        printf("%s\n", target);
+     }
+     \endcode
+     */
+    const xmlChar *opcExternalTargetFirst(opcContainer *container);
+
+    /**
+     \see opcExternalTargetFirst()
+    */
+    const xmlChar *opcExternalTargetNext(opcContainer *container, const xmlChar *target);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_CONTAINER_H */

+ 239 - 0
opc/file.c

@@ -0,0 +1,239 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <opc/file.h>
+#include <stdio.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/globals.h>
+#include <plib/plib.h>
+
+static void *opcFileOpen(const xmlChar *filename, int flags) {
+    char mode[5];
+    int mode_ofs=0;
+    mode[mode_ofs++]='r';
+    mode[mode_ofs++]='b';
+    mode[mode_ofs++]='\0';
+    FILE *file=fopen((const char*)filename, mode); // try to open in READ mode...
+    if (flags & OPC_FILE_WRITE) {
+        if (NULL!=file && flags & OPC_FILE_TRUNC) {
+            fclose(file); file=NULL; // force creating of new file..
+        }
+        if (NULL==file) {
+            // try to create one
+            mode_ofs=0;
+            mode[mode_ofs++]='w';
+            mode[mode_ofs++]='+';
+            mode[mode_ofs++]='b';
+            mode[mode_ofs++]='\0';
+            file=fopen((const char *)filename, mode); // try to open new file
+        } else {
+            fclose(file); // close the read handle...
+            mode_ofs=0;
+            mode[mode_ofs++]='r';
+            mode[mode_ofs++]='+';
+            mode[mode_ofs++]='b';
+            mode[mode_ofs++]='\0';
+            file=fopen((const char *)filename, mode); // try to open existing for read/write
+        }
+    }
+    return file;
+}
+
+static int opcFileClose(void *iocontext) {
+    return fclose((FILE*)iocontext);
+}
+
+static int opcFileRead(void *iocontext, char *buffer, int len) {
+    return fread(buffer, sizeof(char), len, (FILE*)iocontext);
+}
+
+static int opcFileWrite(void *iocontext, const char *buffer, int len) {
+    return fwrite(buffer, sizeof(char), len, (FILE*)iocontext);
+}
+
+static opc_ofs_t opcFileSeek(void *iocontext, opc_ofs_t ofs) {
+    int ret=fseek((FILE*)iocontext, ofs, SEEK_SET);
+    if (ret>=0) {
+        return ftell((FILE*)iocontext);
+    } else {
+        return ret;
+    }
+}
+
+static int opcFileTrim(void *iocontext, opc_ofs_t new_size) {
+#ifdef WIN32
+    return _chsize(fileno((FILE*)iocontext), new_size);
+#else
+    return ftruncate(fileno((FILE*)iocontext), new_size);
+#endif
+}
+
+static int opcFileFlush(void *iocontext) {
+    return fflush((FILE*)iocontext);
+}
+
+static opc_uint32_t opcFileLength(void *iocontext) {
+    opc_ofs_t current=ftell((FILE*)iocontext);
+    OPC_ENSURE(fseek((FILE*)iocontext, 0, SEEK_END)>=0);
+    opc_ofs_t length=ftell((FILE*)iocontext);
+    OPC_ENSURE(fseek((FILE*)iocontext, current, SEEK_SET)>=0);
+    OPC_ASSERT(current==ftell((FILE*)iocontext));
+    return length;
+}
+
+
+struct __opcZipMemContext {
+    const opc_uint8_t *data;
+    opc_uint32_t data_len;
+    opc_uint32_t data_pos;    
+};
+
+static void *opcMemOpen(const opc_uint8_t *data, opc_uint32_t data_len) {
+    struct __opcZipMemContext *mem=(struct __opcZipMemContext *)xmlMalloc(sizeof(struct __opcZipMemContext));
+    memset(mem, 0, sizeof(*mem));
+    mem->data_len=data_len;
+    mem->data_pos=0;
+    mem->data=data;
+    return mem;
+}
+
+static int opcMemClose(void *iocontext) {
+    struct __opcZipMemContext *mem=(struct __opcZipMemContext*)iocontext;
+    xmlFree(mem);
+    return 0;
+}
+
+
+static int opcMemRead(void *iocontext, char *buffer, int len) {
+    struct __opcZipMemContext *mem=(struct __opcZipMemContext*)iocontext;
+    opc_uint32_t max=(mem->data_pos+len<=mem->data_len?len:mem->data_len-mem->data_pos);
+    OPC_ASSERT(max>=0 && mem->data_pos+max<=mem->data_len);
+    memcpy(buffer, mem->data+mem->data_pos, max);
+    mem->data_pos+=max;    
+    return max;
+}
+
+static int opcMemWrite(void *iocontext, const char *buffer, int len) {
+    OPC_ASSERT(0); // not valid for mem
+    return -1;
+}
+
+static opc_ofs_t opcMemSeek(void *iocontext, opc_ofs_t ofs) {
+    struct __opcZipMemContext *mem=(struct __opcZipMemContext*)iocontext;
+    if (ofs<=mem->data_len) {
+        mem->data_pos=ofs;
+    } else {
+        mem->data_pos=mem->data_len;
+    }
+    return mem->data_pos;
+}
+
+static int opcMemTrim(void *iocontext, opc_ofs_t new_size) {
+    OPC_ASSERT(0); // not valid for mem
+    return -1;
+}
+
+static int opcMemFlush(void *iocontext) {
+    return 0;
+}
+
+opc_error_t opcFileInitIO(opcIO_t *io,
+                          opcFileReadCallback *ioread,
+                          opcFileWriteCallback *iowrite,
+                          opcFileCloseCallback *ioclose,
+                          opcFileSeekCallback *ioseek,
+                          opcFileTrimCallback *iotrim,
+                          opcFileFlushCallback *ioflush,
+                          void *iocontext,
+                          pofs_t file_size,
+                          int flags) {
+    opc_bzero_mem(io, sizeof(*io));
+    io->_ioread=ioread;
+    io->_iowrite=iowrite;
+    io->_ioclose=ioclose;
+    io->_ioseek=ioseek;
+    io->_iotrim=iotrim;
+    io->_ioflush=ioflush;
+    io->iocontext=iocontext;
+    io->file_size=file_size;
+    io->flags=flags;
+    return OPC_ERROR_NONE;
+}
+
+opc_error_t opcFileInitIOFile(opcIO_t *io, const xmlChar *filename, int flags) {
+    opc_error_t ret=OPC_ERROR_NONE;
+    void *iocontext=opcFileOpen(filename, flags);
+    if (iocontext!=NULL) {
+        ret=opcFileInitIO(io,
+                          opcFileRead, 
+                          opcFileWrite, 
+                          opcFileClose, 
+                          opcFileSeek, 
+                          opcFileTrim, 
+                          opcFileFlush,
+                          iocontext, 
+                          opcFileLength(iocontext), 
+                          flags);
+    } else {
+        ret=OPC_ERROR_STREAM;
+    }
+    if (OPC_ERROR_NONE!=ret && OPC_ERROR_NONE==io->state.err) io->state.err=ret; // propagate error to stream
+    return ret;
+}
+
+opc_error_t opcFileInitIOMemory(opcIO_t *io, const opc_uint8_t *data, opc_uint32_t data_len, int flags) {
+    opc_error_t ret=OPC_ERROR_NONE;
+    void *iocontext=opcMemOpen(data, data_len);
+    if (iocontext!=NULL) {
+        ret=opcFileInitIO(io, 
+                          opcMemRead, 
+                          opcMemWrite, 
+                          opcMemClose, 
+                          opcMemSeek, 
+                          opcMemTrim, 
+                          opcMemFlush, 
+                          iocontext, 
+                          data_len, 
+                          flags);
+    } else {
+        ret=OPC_ERROR_STREAM;
+    }
+    if (OPC_ERROR_NONE!=ret && OPC_ERROR_NONE==io->state.err) io->state.err=ret; // propagate error to stream
+    return ret;
+}
+
+opc_error_t opcFileCleanupIO(opcIO_t *io) {
+    if (NULL!=io->iocontext) {
+        io->_ioclose(io->iocontext);
+        io->iocontext=NULL;
+    }
+    return OPC_ERROR_NONE;
+}

+ 200 - 0
opc/file.h

@@ -0,0 +1,200 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/file.h
+ The opc module contains the file library functions.
+*/
+#include <opc/config.h>
+
+#ifndef OPC_FILE_H
+#define OPC_FILE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+
+/**
+  Flag for READ access.
+  \hideinitializer
+*/
+#define OPC_FILE_READ  (1<<0)
+
+/**
+  Flag for WRITE access.
+  \hideinitializer
+*/
+#define OPC_FILE_WRITE (1<<1)
+
+/**
+  Flag indicates that file will be truncated when opened.
+  \hideinitializer
+*/
+#define OPC_FILE_TRUNC  (1<<2)
+
+
+    /** 
+      Abstraction for see modes.
+      */
+    typedef enum OPC_FILESEEKMODE_ENUM {
+        opcFileSeekSet = SEEK_SET,
+        opcFileSeekCur = SEEK_CUR,
+        opcFileSeekEnd = SEEK_END
+    } opcFileSeekMode;
+
+     /**
+      Callback to read a file. E.g. for a FILE * context this can be implemented as
+      \code
+      static int opcFileRead(void *iocontext, char *buffer, int len) {
+          return fread(buffer, sizeof(char), len, (FILE*)iocontext);
+      }
+      \endcode
+      */
+    typedef int opcFileReadCallback(void *iocontext, char *buffer, int len);
+
+     /**
+      Callback to write a file. E.g. for a FILE * context this can be implemented as
+      \code
+      static int opcFileWrite(void *iocontext, const char *buffer, int len) {
+          return fwrite(buffer, sizeof(char), len, (FILE*)iocontext);
+      }
+      \endcode
+      */
+    typedef int opcFileWriteCallback(void *iocontext, const char *buffer, int len);
+
+     /**
+      Callback to close a file. E.g. for a FILE * context this can be implemented as
+      \code
+      static int opcFileClose(void *iocontext) {
+          return fclose((FILE*)iocontext);
+      }
+      \endcode
+      */
+    typedef int opcFileCloseCallback(void *iocontext);
+
+     /**
+      Callback to seek a file. E.g. for a FILE * context this can be implemented as
+      \code
+      static opc_ofs_t opcFileSeek(void *iocontext, opc_ofs_t ofs) {
+          int ret=fseek((FILE*)iocontext, ofs, SEEK_SET);
+          if (ret>=0) {
+              return ftell((FILE*)iocontext);
+          } else {
+              return ret;
+          }
+      }
+      \endcode
+      */
+    typedef opc_ofs_t opcFileSeekCallback(void *iocontext, opc_ofs_t ofs);
+
+     /**
+      Callback to trim a file. E.g. for a FILE * context this can be implemented as
+      \code
+      static int opcFileTrim(void *iocontext, opc_ofs_t new_size) {
+      #ifdef WIN32
+          return _chsize(fileno((FILE*)iocontext), new_size);
+      #else
+          return ftruncate(fileno((FILE*)iocontext), new_size);
+      #endif
+      }
+      \endcode
+      */
+    typedef int opcFileTrimCallback(void *iocontext, opc_ofs_t new_size);
+
+     /**
+      Callback to flush a file. E.g. for a FILE * context this can be implemented as
+      \code
+      static int opcFileFlush(void *iocontext) {
+          return fflush((FILE*)iocontext);
+      }
+      \endcode
+      */
+    typedef int opcFileFlushCallback(void *iocontext);
+
+    /**
+      Represents a state of a file, i.e. file position (buf_pos) and error status (err).
+      */
+    typedef struct OPC_FILERAWSTATE_STRUCT {
+        opc_error_t err;
+        opc_ofs_t   buf_pos; // current pos in file
+    } opcFileRawState;
+
+    /**
+     File IO context.
+     */
+    typedef struct OPC_IO_STRUCT {
+        opcFileReadCallback *_ioread;
+        opcFileWriteCallback *_iowrite;
+        opcFileCloseCallback *_ioclose;
+        opcFileSeekCallback *_ioseek;
+        opcFileTrimCallback *_iotrim;
+        opcFileFlushCallback *_ioflush;
+        void *iocontext;
+        int flags;
+        opcFileRawState state;
+        opc_ofs_t file_size;
+    } opcIO_t;
+
+    /**
+      Initialize an IO context.
+      */
+    opc_error_t opcFileInitIO(opcIO_t *io,
+                              opcFileReadCallback *ioread,
+                              opcFileWriteCallback *iowrite,
+                              opcFileCloseCallback *ioclose,
+                              opcFileSeekCallback *ioseek,
+                              opcFileTrimCallback *iotrim,
+                              opcFileFlushCallback *ioflush,
+                              void *iocontext,
+                              pofs_t file_size,
+                              int flags);
+
+    /**
+      Initialize an IO context for a file.
+      */
+    opc_error_t opcFileInitIOFile(opcIO_t *io, const xmlChar *filename, int flags);
+
+    /**
+      Initialize an IO for memory.
+      \warning Currently supports READ-ONLY file access.
+      */
+    opc_error_t opcFileInitIOMemory(opcIO_t *io, const opc_uint8_t *data, opc_uint32_t data_len, int flags);
+
+    /**
+      Cleanup an IO context, i.e. release all system resources.
+      */
+    opc_error_t opcFileCleanupIO(opcIO_t *io);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_FILE_H */

+ 205 - 0
opc/helper.c

@@ -0,0 +1,205 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <opc/helper.h>
+
+static puint32_t opcHelperEncodeFilename(const xmlChar *name, char *buf, int buf_len, opc_bool_t rels_segment) {
+    int name_len=xmlStrlen(name);
+    int len=name_len;
+    int buf_ofs=0;
+    int rels_ofs=name_len;
+    if (rels_segment) {
+        while(rels_ofs>0 && name[--rels_ofs]!='/'); // find last "/"
+        if (name[rels_ofs]!='/') {
+            buf_ofs+=snprintf(buf+buf_ofs, buf_len-buf_ofs, "_rels/");
+        }
+    }
+    const xmlChar *rel_ch=name+rels_ofs;
+    int ch=0;
+    while(name_len>0 && 0!=(ch=xmlGetUTF8Char(name, &len)) && len>0 && len<=name_len && (NULL==buf || buf_ofs<buf_len)) {
+        switch(ch) {
+        case '/':
+            if (name==rel_ch) {
+                buf_ofs+=snprintf(buf+buf_ofs, buf_len-buf_ofs, "/_rels");
+            }
+        case ':':
+        case '@':
+        case '-':
+        case '.':
+        case '_':
+        case '~':
+        case '!':
+        case '$':
+        case '&':
+        case '\'':
+        case '(':
+        case ')':
+        case '*':
+        case '+':
+        case ',':
+        case ';':
+        case '=':
+        case '[': // for internal use only
+        case ']': // for internal use only
+            if (NULL!=buf && buf_ofs<buf_len) buf[buf_ofs]=ch; buf_ofs++;
+            break;
+        default:
+            if ((ch>='A' && ch<='Z') || (ch>='a' && ch<='z') || (ch>='0' && ch<='9')) {
+                if (NULL!=buf) buf[buf_ofs]=ch; buf_ofs++;
+            } else if (NULL==buf || (buf_ofs+3<=buf_len && 3==snprintf(buf+buf_ofs, 3, "%%%02X", ch))) {
+                buf_ofs+=3;
+            } else {
+                buf_ofs=0; buf_len=0; // indicate error
+            }
+        }
+        name_len-=len;
+        name+=len;
+    }
+    if (rels_segment) {
+        buf_ofs+=snprintf(buf+buf_ofs, buf_len-buf_ofs, ".rels");
+    }
+    return buf_ofs;
+}
+
+static puint32_t opcHelperFilenameAppendPiece(opc_uint32_t segment_number, opc_bool_t last_segment, char *buf, int buf_ofs, int buf_len) {
+    if (buf_ofs>0) { // only append to non-empty filenames
+        int len=0;
+        if (0==segment_number && last_segment) {
+            // only one segment, do not append anything...
+        } else if (last_segment) {
+            OPC_ASSERT(segment_number>0); // we have a last segment
+            if (NULL==buf || (buf_ofs<buf_len && (len=snprintf(buf+buf_ofs, buf_len-buf_ofs, "/[%i].last.piece", segment_number))>14)) {
+                buf_ofs+=len;
+                buf_len-=len;
+            }
+        } else {
+            OPC_ASSERT(!last_segment); // we have a segment with more to come...
+            if (NULL==buf || (buf_ofs<buf_len && (len=snprintf(buf+buf_ofs, buf_len-buf_ofs, "/[%i].piece", segment_number))>9)) {
+                buf_ofs+=len;
+                buf_len-=len;
+            }
+        }
+    }
+    return buf_ofs;
+}
+
+
+
+
+opc_uint16_t opcHelperAssembleSegmentName(char *out, opc_uint16_t out_size, const xmlChar *name, opc_uint32_t segment_number, opc_uint32_t next_segment_id, opc_bool_t rels_segment, opc_uint16_t *out_max) {
+    opc_uint16_t out_length=opcHelperEncodeFilename(name, out, out_size, rels_segment); 
+    opc_uint16_t const _out_max=out_length+24; // file+|/[4294967296].last.piece|=file+24
+                                               // _rels/file.rels=|_rels/|+|.rels|=6+5=11
+    out_length=opcHelperFilenameAppendPiece(segment_number, next_segment_id, out, out_length, out_size);
+    OPC_ASSERT(out_length<=out_size);
+    OPC_ASSERT(out_length<=_out_max);
+    if (NULL!=out_max) *out_max=_out_max;
+    return out_length;
+}
+
+
+opc_error_t opcHelperSplitFilename(opc_uint8_t *filename, opc_uint32_t filename_length, opc_uint32_t *segment_number, opc_bool_t *last_segment, opc_bool_t *rel_segment) {
+    opc_error_t ret=OPC_ERROR_STREAM;
+    if (NULL!=segment_number) *segment_number=0;
+    if (NULL!=last_segment) *last_segment=OPC_TRUE;
+    if (NULL!=rel_segment) *rel_segment=OPC_FALSE;
+    if (filename_length>7 // "].piece"  suffix
+        && filename[filename_length-7]==']'
+        && filename[filename_length-6]=='.'
+        && filename[filename_length-5]=='p'
+        && filename[filename_length-4]=='i'
+        && filename[filename_length-3]=='e'
+        && filename[filename_length-2]=='c'
+        && filename[filename_length-1]=='e') {
+        opc_uint32_t i=filename_length-7;
+        filename[i--]='\0';
+        while(i>0 && filename[i]>='0' && filename[i]<='9') {
+            i--;
+        }
+        if (i>2 && filename[i-2]=='/' && filename[i-1]=='[' && '\0'!=filename[i]) {
+            if (NULL!=segment_number) *segment_number=atoi((char*)(filename+i));
+            if (NULL!=last_segment) *last_segment=OPC_FALSE;
+            filename[i-2]='\0';
+            ret=OPC_ERROR_NONE;
+        }
+    } else if (filename_length>12 // "].last.piece"  suffix
+        && filename[filename_length-12]==']'
+        && filename[filename_length-11]=='.'
+        && filename[filename_length-10]=='l'
+        && filename[filename_length-9]=='a'
+        && filename[filename_length-8]=='s'
+        && filename[filename_length-7]=='t'
+        && filename[filename_length-6]=='.'
+        && filename[filename_length-5]=='p'
+        && filename[filename_length-4]=='i'
+        && filename[filename_length-3]=='e'
+        && filename[filename_length-2]=='c'
+        && filename[filename_length-1]=='e') {
+        opc_uint32_t i=filename_length-12;
+        filename[i--]='\0';
+        while(i>0 && filename[i]>='0' && filename[i]<='9') {
+            i--;
+        }
+        if (i>2 && filename[i-2]=='/' &&  filename[i-1]=='[' && '\0'!=filename[i]) {
+            if (NULL!=segment_number) *segment_number=atoi((char*)(filename+i));
+            if (NULL!=last_segment) *last_segment=OPC_TRUE;
+            filename[i-2]='\0';
+            ret=OPC_ERROR_NONE;
+        }
+    } else if (filename_length>5 // ".rels"  suffix
+        && filename[filename_length-5]=='.'
+        && filename[filename_length-4]=='r'
+        && filename[filename_length-3]=='e'
+        && filename[filename_length-2]=='l'
+        && filename[filename_length-1]=='s') {
+        opc_uint32_t i=filename_length-5;
+        while(i>0 && filename[i-1]!='/') i--;
+        //"_rels/"
+        if (i>=6
+            && filename[i-6]=='_' 
+            && filename[i-5]=='r' 
+            && filename[i-4]=='e' 
+            && filename[i-3]=='l' 
+            && filename[i-2]=='s' 
+            && filename[i-1]=='/') {
+            opc_uint32_t j=i;
+            for(;j<filename_length-5;j++) {
+                filename[j-6]=filename[j];
+            }
+            filename[j-6]=0;
+            if (NULL!=rel_segment) *rel_segment=OPC_TRUE;
+        }
+        ret=OPC_ERROR_NONE;
+    } else {
+        ret=OPC_ERROR_NONE;
+    }
+    return ret;
+}

+ 60 - 0
opc/helper.h

@@ -0,0 +1,60 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/helper.h
+  Contains helper functions for the opc module.
+*/
+#include <opc/config.h>
+
+#ifndef OPC_HELPER_H
+#define OPC_HELPER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+
+    /**
+      Constructs a segment name.
+      */
+    opc_uint16_t opcHelperAssembleSegmentName(char *out, opc_uint16_t out_size, const xmlChar *name, opc_uint32_t segment_number, opc_uint32_t next_segment_id, opc_bool_t rels_segment, opc_uint16_t *out_max);
+
+    /**
+      Splits a filename into the segment informations.
+      */
+    opc_error_t opcHelperSplitFilename(opc_uint8_t *filename, opc_uint32_t filename_length, opc_uint32_t *segment_number, opc_bool_t *last_segment, opc_bool_t *rel_segment);
+
+#endif /* OPC_HELPER_H */

+ 34 - 0
opc/inputstream.c

@@ -0,0 +1,34 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+#include "internal.h"
+

+ 74 - 0
opc/inputstream.h

@@ -0,0 +1,74 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/inputstream.h
+ 
+ */
+#include <opc/config.h>
+
+#ifndef OPC_INPUTSTREAM_H
+#define OPC_INPUTSTREAM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+    /**
+      Internal type which represents a binary input stream.
+      */
+    typedef struct OPC_CONTAINER_INPUTSTREAM_STRUCT opcContainerInputStream;
+
+    /**
+      Opens the part \c name of the \c container for reading.
+      */
+    opcContainerInputStream* opcContainerOpenInputStream(opcContainer *container, const xmlChar *name);
+
+    /**
+     Reads maximal \c buffer_len bytes from the input \c stream to \c buffer. 
+     \return The number of byes read or "0" in case of an error or end-of-stream.
+     */
+    opc_uint32_t opcContainerReadInputStream(opcContainerInputStream* stream, opc_uint8_t *buffer, opc_uint32_t buffer_len);
+
+    /**
+      Closes the input stream and releases all system resources.
+      */
+    opc_error_t opcContainerCloseInputStream(opcContainerInputStream* stream);
+
+    /**
+      Returns the type of compression used for the stream.
+      */
+    opcCompressionOption_t opcContainerGetInputStreamCompressionOption(opcContainerInputStream* stream);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_INPUTSTREAM_H */

+ 237 - 0
opc/internal.h

@@ -0,0 +1,237 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/* @file opc/internal.h
+ Contains all internally shared datastructures.
+ This file contains non-public definitions and will not be available for users in the SDK.
+*/
+
+#ifndef OPC_INTERNAL_H
+#define OPC_INTERNAL_H
+
+#include <opc/config.h>
+#include <opc/container.h>
+#include <opc/zip.h>
+#include <zlib.h>
+#include <mce/textreader.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+
+    typedef struct OPC_FILERAWBUFFER_STRUCT {
+        opcFileRawState state;
+        puint32_t   buf_ofs;
+        puint32_t   buf_len;
+        opc_uint8_t buf[OPC_DEFLATE_BUFFER_SIZE];
+    } opcFileRawBuffer;
+
+
+    typedef struct OPC_ZIPSEGMENT_STRUCT {
+        opc_uint32_t deleted_segment :1;
+        opc_uint32_t rels_segment :1;
+        opc_uint32_t next_segment_id;
+        const xmlChar *partName; // NOT!!! owned by me... owned by opcContainer
+        opc_ofs_t stream_ofs;
+        opc_ofs_t segment_size;
+        opc_uint16_t padding;
+        opc_uint32_t header_size;
+        opc_uint16_t bit_flag;
+        opc_uint32_t crc32;
+        opc_uint16_t compression_method;
+        opc_ofs_t compressed_size;
+        opc_ofs_t uncompressed_size;
+        opc_uint32_t growth_hint; 
+    } opcZipSegment;
+
+    struct OPC_ZIP_STRUCT {
+        opcIO_t *io;
+        opc_uint32_t first_free_segment_id;
+        opcZipSegment *segment_array;
+        opc_uint32_t segment_items;
+    };
+
+    typedef struct OPC_ZIPINFLATESTATE_STRUCT {
+        z_stream stream;
+        opc_uint16_t compression_method;
+        int inflate_state;
+        opc_ofs_t compressed_size;
+    } opcZipInflateState;
+
+    struct OPC_ZIPOUTPUTSTREAM_STRUCT {
+        opc_uint32_t segment_id;
+        opc_uint16_t compression_method;
+        opc_uint32_t crc32;
+        z_stream stream;
+        int inflate_state;
+        opc_uint32_t buf_len;
+        opc_uint32_t buf_ofs;
+        opc_uint32_t buf_size;
+        opc_uint8_t *buf /*[buf_size]*/;
+    };
+
+    struct OPC_ZIPINPUTSTREAM_STRUCT {
+        opc_uint32_t segment_id;
+        opcZipInflateState inflateState;
+        opcFileRawBuffer rawBuffer;
+    };
+
+    typedef struct OPC_QNAME_LEVEL {
+        const xmlChar *ns;
+        xmlChar *ln;
+        opc_uint32_t level;
+        opc_uint32_t alternatecontent_handled : 1;
+    } opcQNameLevel_t;
+
+    struct OPC_CONTAINER_INPUTSTREAM_STRUCT {
+        opcZipInputStream *stream;
+        opcContainer *container; // weak reference
+        opc_error_t error;
+        opc_uint32_t reader_consume_element : 1;
+        opc_uint32_t reader_element_handled : 1;
+        opc_uint32_t reader_mce : 1;
+    };
+
+    struct OPC_CONTAINER_OUTPUTSTREAM_STRUCT {
+        opcZipOutputStream *stream;
+        opc_uint32_t segment_id;  
+        opcContainer *container; // weak reference
+        const xmlChar *partName;
+        opc_bool_t rels_segment;
+    };
+
+    typedef struct OPC_CONTAINER_RELATION_TYPE_STRUCT {
+        xmlChar *type;
+    } opcContainerRelationType;
+
+    typedef struct OPC_CONTAINER_EXTERNAL_RELATION_STRUCT {
+        xmlChar *target;
+    } opcContainerExternalRelation;
+
+
+    struct OPC_RELATION_STRUCT {
+        xmlChar *part_name; // owned by part array
+        xmlChar *relation_id; // owned by relation array
+    };
+
+    typedef struct OPC_CONTAINER_RELATION_STRUCT {
+        opc_uint32_t relation_id;
+        xmlChar *relation_type; // owned by relationtypes_array
+        opc_uint32_t target_mode; // 0==internal, 1==external
+        xmlChar* target_ptr; // 0==targetMode: points to xmlChar owned part_array, 1==targetMode: points to xmlChar owned by externalrelation_array
+    } opcContainerRelation;
+
+    typedef struct OPC_CONTAINER_PART_STRUCT {
+        xmlChar *name;
+        const xmlChar *type; // owned by type_array
+        opc_uint32_t first_segment_id;
+        opc_uint32_t last_segment_id;
+        opc_uint32_t segment_count;
+        opc_uint32_t rel_segment_id;
+        opcContainerRelation *relation_array;
+        opc_uint32_t relation_items;
+    } opcContainerPart;
+
+    typedef struct OPC_CONTAINER_PART_PREFIX_STRUCT {
+        xmlChar *prefix;
+    } opcContainerRelPrefix;
+
+    #define OPC_CONTAINER_RELID_COUNTER_NONE 0xFFFF
+    #define OPC_CONTAINER_RELID_COUNTER(rel) ((rel)&0xFFFF)
+    #define OPC_CONTAINER_RELID_PREFIX(rel) (((rel)>>16)&0xFFFF)
+
+    typedef struct OPC_CONTAINER_TYPE_STRUCT {
+        xmlChar *type;
+    } opcContainerType;
+
+    typedef struct OPC_CONTAINER_EXTENSION_STRUCT {
+        xmlChar *extension;
+        const xmlChar *type; // owned by opcContainerType
+    } opcContainerExtension;
+
+    struct OPC_CONTAINER_STRUCT {
+        opcIO_t io;
+        opcZip *storage;
+        opcContainerOpenMode mode;
+
+        opcContainerPart *part_array;
+        opc_uint32_t part_items;
+        opcContainerRelPrefix *relprefix_array;
+        opc_uint32_t relprefix_items;
+        opcContainerType *type_array;
+        opc_uint32_t type_items;
+        opcContainerExtension *extension_array;
+        opc_uint32_t extension_items;
+        opcContainerRelationType *relationtype_array;
+        opc_uint32_t relationtype_items;
+        opcContainerExternalRelation *externalrelation_array;
+        opc_uint32_t externalrelation_items;
+        opc_uint32_t content_types_segment_id;
+        opc_uint32_t rels_segment_id;
+        opcContainerRelation *relation_array;
+        opc_uint32_t relation_items;
+        void *userContext;
+    };
+
+    opc_error_t opcXmlReaderOpenEx(opcContainer *container, mceTextReader_t *mceTextReader, const xmlChar *partName, opc_bool_t rels_segment, const char * URL, const char * encoding, int options);
+    opcContainerInputStream* opcContainerOpenInputStreamEx(opcContainer *container, const xmlChar *name, opc_bool_t rels_segment);
+    opcContainerOutputStream* opcContainerCreateOutputStreamEx(opcContainer *container, const xmlChar *name, opc_bool_t rels_segment, opcCompressionOption_t compression_option);
+
+
+    opcContainerExtension *opcContainerInsertExtension(opcContainer *container, const xmlChar *extension, opc_bool_t insert);
+    opcContainerPart *opcContainerInsertPart(opcContainer *container, const xmlChar *name, opc_bool_t insert);
+    opc_error_t opcContainerDeletePart(opcContainer *container, const xmlChar *name);
+    opcContainerRelation *opcContainerFindRelation(opcContainer *container, opcContainerRelation *relation_array, opc_uint32_t relation_items, opcRelation relation);
+    opc_error_t opcContainerDeleteRelation(opcContainer *container, opcContainerRelation **relation_array, opc_uint32_t *relation_items, opcRelation relation);
+    opcContainerRelation *opcContainerInsertRelation(opcContainerRelation **relation_array, opc_uint32_t *relation_items, 
+                                                     opc_uint32_t relation_id,
+                                                     xmlChar *relation_type,
+                                                     opc_uint32_t target_mode, xmlChar *target_ptr);
+    opcContainerExternalRelation*insertExternalRelation(opcContainer *container, const xmlChar *target, opc_bool_t insert);
+    opcContainerRelationType *opcContainerInsertRelationType(opcContainer *container, const xmlChar *type, opc_bool_t insert);
+    opcContainerType *insertType(opcContainer *container, const xmlChar *type, opc_bool_t insert);
+
+    opc_bool_t opcContainerDeletePartEx(opcContainer *container, const xmlChar *partName, opc_bool_t rels_segment);
+
+    opcContainerRelation *opcContainerFindRelationById(opcContainer *container, opcContainerRelation *relation_array, opc_uint32_t relation_items, const xmlChar *relation_id);
+
+    opc_error_t opcQNameLevelAdd(opcQNameLevel_t **list_array, opc_uint32_t *list_items, opcQNameLevel_t *item);
+    opcQNameLevel_t* opcQNameLevelLookup(opcQNameLevel_t *list_array, opc_uint32_t list_items, const xmlChar *ns, const xmlChar *ln);
+    opc_error_t opcQNameLevelCleanup(opcQNameLevel_t *list_array, opc_uint32_t *list_items, opc_uint32_t level, opc_uint32_t *max_level);
+    opc_error_t opcQNameLevelPush(opcQNameLevel_t **list_array, opc_uint32_t *list_items, opcQNameLevel_t *item);
+    opc_bool_t opcQNameLevelPopIfMatch(opcQNameLevel_t *list_array, opc_uint32_t *list_items, const xmlChar *ns, const xmlChar *ln, opc_uint32_t level);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+
+#endif /* OPC_INTERNAL_H */

+ 132 - 0
opc/main.c

@@ -0,0 +1,132 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+#include <stdio.h>
+
+/** @mainpage libopc
+
+ This is the API documentation of the libopc project. 
+
+ API headers can be found in the "Files" section.
+ 
+ Samples can be found in the "Examples" section.
+ 
+ */
+
+/** \example opc_helloworld.c
+ Demonstrates the the use of \ref opcInitLibrary and \ref opcFreeLibrary.
+ */
+
+/** \example opc_dump.c
+ Demonstrates the the use of \ref opcContainerOpen, \ref opcContainerClose and \redf opcContainerDump.
+ */
+
+/** \example opc_extract.c
+ Demonstrates binary input stream access to an OPC container.
+ */
+
+/** \example opc_zipwrite.c
+ Demonstrates low level ZIP write functionality as needed by the high level opcContainer API.
+ */
+
+
+/** \example opc_zipread.c
+ Demonstrates low level ZIP read functionality as needed by the high level opcContainer API.
+ */
+
+/** \example opc_zipextract.c
+ Demonstrates low level ZIP read functionality as needed by the high level opcContainer API.
+ */
+
+/** \example opc_xml.c
+ Demonstrates basic non-MCE XML read access.
+ */
+
+/** \example opc_xml2.c
+ Demonstrates basic non-MCE XML read access via helper macros.
+ */
+
+/** \example mce_read.c
+ Demonstrates basic MCE proprocessing.
+ */
+
+/** \example mce_write.c
+ Demonstrates basic MCE proprocessing.
+*/
+
+/** \example opc_image.c
+ Sample program which will extract all images from an OPC container.
+ E.g. opc_dump hello.pptx will extract all pictures from "hello.pptx" in the current directory.
+ The call opc_dump hello.pptx C:\Users\flr\Pictures will extract all pictures from "hello.pptx" in the directory "C:\Users\flr\Pictures".
+ */
+
+/** \example opc_mem.c
+ Demonstrates the the use of \ref opcContainerOpenMem, i.e. how to use "in-memory" containers.
+ */
+
+/** \example opc_part.c
+ Demonstrates how to dump a part from an OPC container. Ussage opc_dump [container] [part-name]. E.g. opc_dump sample.docx "word/document.xml".
+ */
+
+/** \example opc_relation.c
+ Demonstrates how to traverse all relations in an OPC container using the API.
+ */
+
+/** \example opc_text.c
+ Sample program which will extract all text form an Word document and dump it as HTML.
+ */
+
+/** \example opc_trim.c
+ Opens an OPC containers and saves it back in "trimming" mode, which will reduce the size as much as possible.
+ */
+
+/** \example opc_type.c
+ Demonstrate how to corretly get the type of an Office document.
+ */
+
+/** \example opc_generate.c
+ Sample program which will read an OPC container and generate a "C" file which uses the API to generate the passed container.
+ */
+
+
+int main( int argc, const char* argv[] )
+{
+    if (OPC_ERROR_NONE==opcInitLibrary()) {
+        printf("libopc as well as zlib and libxml2 are ready to use.\n");
+        opcFreeLibrary();
+        return 0;
+    }  else  {
+        printf("error initializing libopc.\n ");
+        return 1;
+    }
+}
+

+ 43 - 0
opc/opc.c

@@ -0,0 +1,43 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <opc/opc.h>
+#include <libxml/xmlreader.h>
+
+opc_error_t opcInitLibrary() {
+    xmlInitParser();
+    return OPC_ERROR_NONE;
+}
+
+opc_error_t opcFreeLibrary() {
+    xmlCleanupParser();
+    return OPC_ERROR_NONE;
+}

+ 73 - 0
opc/opc.h

@@ -0,0 +1,73 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/opc.h
+ The opc module contains the basic library functions.
+*/
+#include <opc/config.h>
+#include <opc/container.h>
+#include <opc/part.h>
+#include <opc/relation.h>
+#include <opc/inputstream.h>
+#include <opc/outputstream.h>
+#include <opc/zip.h>
+#include <opc/xmlreader.h>
+#include <opc/xmlwriter.h>
+#include <opc/properties.h>
+
+#ifndef OPC_OPC_H
+#define OPC_OPC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+    
+    /**
+     * Initialize libopc.
+     * Sample:
+     * \include opc_helloworld.c
+     * @return Non-zero if successful.
+     */
+    opc_error_t opcInitLibrary();
+
+    /**
+     * Free libopc. Clean up all resources.
+     * @return Non-zero if successful.
+     * \see opcInitLibrary.
+     */
+    opc_error_t opcFreeLibrary();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_OPC_H */

+ 33 - 0
opc/outputstream.c

@@ -0,0 +1,33 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+

+ 71 - 0
opc/outputstream.h

@@ -0,0 +1,71 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/outputstream.h
+ 
+ */
+#include <opc/config.h>
+
+#ifndef OPC_OUTPUTSTREAM_H
+#define OPC_OUTPUTSTREAM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+    /**
+      Internal type which represents a binary output stream.
+      */
+    typedef struct OPC_CONTAINER_OUTPUTSTREAM_STRUCT opcContainerOutputStream;
+
+    /** 
+      Open the part \c name or writing in \c container with compression \c compression_option.
+      \note Make sure the part exists! 
+      \see opcPartCreate.
+      */
+    opcContainerOutputStream* opcContainerCreateOutputStream(opcContainer *container, const xmlChar *name, opcCompressionOption_t compression_option);
+
+    /**
+      Write \c buffer_len bytes from \c buffer to \c stream. 
+      \return Returns the number of bytes written.
+      */
+    opc_uint32_t opcContainerWriteOutputStream(opcContainerOutputStream* stream, const opc_uint8_t *buffer, opc_uint32_t buffer_len);
+
+    /**
+      Close the \c stream and free all associated resources.
+      */
+    opc_error_t opcContainerCloseOutputStream(opcContainerOutputStream* stream);
+        
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_OUTPUTSTREAM_H */

+ 117 - 0
opc/part.c

@@ -0,0 +1,117 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+#include "internal.h"
+
+
+static opcPart opcPartOpenEx(opcContainer *container, 
+                    const xmlChar *absolutePath, 
+                    const xmlChar *type,                         
+                    int flags,
+                    opc_bool_t create_part) {
+    opcContainerPart *part=opcContainerInsertPart(container, (absolutePath[0]=='/'?absolutePath+1:absolutePath), create_part);
+    if (NULL!=part) {
+        if (create_part && NULL==part->type) {
+            opcContainerType *ct=insertType(container, type, OPC_TRUE);
+            OPC_ASSERT(NULL!=ct && 0==xmlStrcmp(ct->type, type));
+            part->type=ct->type;
+        }
+        return part->name;
+    } else {
+        return OPC_PART_INVALID;
+    }
+}
+
+opcPart opcPartFind(opcContainer *container, 
+                    const xmlChar *absolutePath, 
+                    const xmlChar *type,
+                    int flags) {
+    return opcPartOpenEx(container, absolutePath, type, flags, OPC_FALSE);
+}
+
+opcPart opcPartCreate(opcContainer *container, 
+                    const xmlChar *absolutePath, 
+                    const xmlChar *type,
+                    int flags) {
+    return opcPartOpenEx(container, absolutePath, type, flags, OPC_TRUE);
+}
+
+const xmlChar *opcPartGetType(opcContainer *c,  opcPart part) {
+    return opcPartGetTypeEx(c, part, OPC_FALSE);
+}
+
+const xmlChar *opcPartGetTypeEx(opcContainer *c, opcPart part, opc_bool_t override_only) {
+   OPC_ASSERT(OPC_PART_INVALID!=part);
+    opcContainerPart *cp=(OPC_PART_INVALID!=part?opcContainerInsertPart(c, part, OPC_FALSE):NULL);
+    const xmlChar *type=(NULL!=cp?cp->type:NULL);
+    if (NULL==type && NULL!=cp && !override_only) {
+        xmlChar *name=cp->name;
+        int l=(NULL!=name?xmlStrlen(name):0);
+        while(l>0 && name[l]!='.') l--;
+        if (l>0) { 
+            l++;
+            opcContainerExtension *ct=opcContainerInsertExtension(c, name+l, OPC_FALSE);
+            type=(NULL!=ct?ct->type:NULL);
+        } else {
+            type=NULL; // no extension
+        }
+    }
+    return type;
+}
+
+
+opc_error_t opcPartDelete(opcContainer *container, const xmlChar *absolutePath) {
+    return opcContainerDeletePart(container, (absolutePath[0]=='/'?absolutePath+1:absolutePath));
+}
+
+
+opcPart opcPartGetFirst(opcContainer *container) {
+    return (NULL!=container && container->part_items>0?container->part_array[0].name:OPC_PART_INVALID);
+}
+
+opcPart opcPartGetNext(opcContainer *container, opcPart part) {
+    opcContainerPart *cp=(NULL!=container?opcContainerInsertPart(container, part, OPC_FALSE):NULL);
+    if (NULL!=cp) {
+        do { cp++; } while(cp<container->part_array+container->part_items && -1==cp->first_segment_id);
+    }
+    return (NULL!=cp && cp<container->part_array+container->part_items?cp->name:NULL);
+}
+
+opc_ofs_t opcPartGetSize(opcContainer *c, opcPart part) {
+   OPC_ASSERT(OPC_PART_INVALID!=part);
+    opcContainerPart *cp=(OPC_PART_INVALID!=part?opcContainerInsertPart(c, part, OPC_FALSE):NULL);
+    if (NULL!=cp && cp->first_segment_id>=0 && cp->first_segment_id<c->storage->segment_items) {
+        return c->storage->segment_array[cp->first_segment_id].uncompressed_size;
+    } else {
+        return 0;
+    }
+}

+ 118 - 0
opc/part.h

@@ -0,0 +1,118 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/part.h
+ 
+ */
+#include <opc/config.h>
+
+#ifndef OPC_PART_H
+#define OPC_PART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+    /**
+     Handle to an OPC part created by \ref opcPartOpen.
+     \see opcPartOpen.
+     */
+    typedef xmlChar* opcPart;
+
+/**
+  Represents an invalid (resp. NULL) part.
+  In releations OPC_PART_INVALID also represents the root part.
+  \hideinitializer
+  */
+#define OPC_PART_INVALID NULL
+
+    /**
+     Find a part in a \ container by \c absolutePath and/or \c type.
+     Currently no flags are supported.
+     */
+    opcPart opcPartFind(opcContainer *container, 
+                        const xmlChar *absolutePath, 
+                        const xmlChar *type,
+                        int flags);
+
+    /**
+     Creates a part in a \ container with \c absolutePath and \c type.
+     Currently no flags are supported.
+     */
+    opcPart opcPartCreate(opcContainer *container, 
+                          const xmlChar *absolutePath, 
+                          const xmlChar *type,
+                          int flags);
+
+    /**
+      Returns the type of the container.
+      The string is interned and must not be freed.
+      */
+    const xmlChar *opcPartGetType(opcContainer *c, opcPart part);
+
+    /**
+      Returns the type of the container. 
+      If \c override_only then the return value will be NULL for parts not having an override type.
+      The string is interned and must not be freed.
+      */
+    const xmlChar *opcPartGetTypeEx(opcContainer *c, opcPart part, opc_bool_t override_only);
+
+    /**
+     Deleted that part \c absolutePath in the \c container.
+     */
+    opc_error_t opcPartDelete(opcContainer *container, const xmlChar *absolutePath);
+
+    /**
+      Get the first part.
+      \code
+      for(opcPart part=opcPartGetFirst(c);OPC_PART_INVALID!=part;part=opcPartGetNext(c, part)) {
+        printf("%s; \n", part, opcPartGetType(c, part));
+      }
+      \endcode 
+      */
+    opcPart opcPartGetFirst(opcContainer *container);
+
+    /**
+     Get the next part.
+     \see opcPartGetFirst
+      */
+    opcPart opcPartGetNext(opcContainer *container, opcPart part);
+
+    /**
+      Returns the size in bytes of the \c part.
+      */
+    opc_ofs_t opcPartGetSize(opcContainer *c, opcPart part);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_PART_H */

+ 292 - 0
opc/properties.c

@@ -0,0 +1,292 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/properties.h>
+#include <libxml/xmlmemory.h>
+#include <opc/xmlreader.h>
+#include <mce/textreader.h>
+#include <mce/textwriter.h>
+
+opc_error_t opcCorePropertiesInit(opcProperties_t *cp) {
+    opc_bzero_mem(cp, sizeof(*cp));
+    return OPC_ERROR_NONE;
+}
+
+static void opcDCSimpleTypeFree(opcDCSimpleType_t *v) {
+    if (NULL!=v) {
+        if (NULL!=v->lang) xmlFree(v->lang);
+        if (NULL!=v->str) xmlFree(v->str);
+    }
+}
+
+opc_error_t opcCorePropertiesCleanup(opcProperties_t *cp) {
+    if (NULL!=cp->category) xmlFree(cp->category);
+    if (NULL!=cp->contentStatus) xmlFree(cp->contentStatus);
+    if (NULL!=cp->created) xmlFree(cp->created);
+    opcDCSimpleTypeFree(&cp->creator);
+    opcDCSimpleTypeFree(&cp->description);
+    opcDCSimpleTypeFree(&cp->identifier);
+    for(opc_uint32_t i=0;i<cp->keyword_items;i++) {
+        opcDCSimpleTypeFree(&cp->keyword_array[i]);
+    }
+    if (NULL!=cp->keyword_array) {
+        xmlFree(cp->keyword_array);
+    }
+    opcDCSimpleTypeFree(&cp->language);
+    if (NULL!=cp->lastModifiedBy) xmlFree(cp->lastModifiedBy);
+    if (NULL!=cp->lastPrinted) xmlFree(cp->lastPrinted);
+    if (NULL!=cp->modified) xmlFree(cp->modified);
+    if (NULL!=cp->revision) xmlFree(cp->revision);
+    opcDCSimpleTypeFree(&cp->subject);
+    opcDCSimpleTypeFree(&cp->title);
+    if (NULL!=cp->version) xmlFree(cp->version);
+    return OPC_ERROR_NONE;
+}
+
+opc_error_t opcCorePropertiesSetString(xmlChar **prop, const xmlChar *str) {
+    if (NULL!=prop) {
+        if (NULL!=*prop) xmlFree(*prop);
+        *prop=xmlStrdup(str);
+    }
+    return OPC_ERROR_NONE;
+}
+
+opc_error_t opcCorePropertiesSetStringLang(opcDCSimpleType_t *prop, const xmlChar *str, const xmlChar *lang) {
+    if (NULL!=prop) {
+        if (NULL!=prop->str) xmlFree(prop->str);
+        if (NULL!=prop->lang) xmlFree(prop->lang);
+        prop->str=(NULL!=str?xmlStrdup(str):NULL);
+        prop->lang=(NULL!=lang?xmlStrdup(lang):NULL);
+    }
+    return OPC_ERROR_NONE;
+}
+
+static const char cp_ns[]="http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
+static const char dc_ns[]="http://purl.org/dc/elements/1.1/";
+static const char dcterms_ns[]="http://purl.org/dc/terms/";
+static const char xml_ns[]="http://www.w3.org/XML/1998/namespace";
+static const char xsi_ns[]="http://www.w3.org/2001/XMLSchema-instance";
+
+static void _opcCorePropertiesAddKeywords(opcProperties_t *cp, const xmlChar *keywords, const xmlChar *lang) {
+    int ofs=0;
+    do {
+        while(0!=keywords[ofs] && (' '==keywords[ofs] || '\t'==keywords[ofs] || '\r'==keywords[ofs] || '\n'==keywords[ofs])) ofs++;
+        int start=ofs;
+        while(0!=keywords[ofs] && ';'!=keywords[ofs]) ofs++;
+        int end=ofs;
+        while(end>start && (' '==keywords[end-1] || '\t'==keywords[end-1] || '\r'==keywords[end-1] || '\n'==keywords[end-1])) end--;
+        if (end>start) {
+            cp->keyword_array=(opcDCSimpleType_t*)xmlRealloc(cp->keyword_array, (cp->keyword_items+1)*sizeof(opcDCSimpleType_t));
+            cp->keyword_array[cp->keyword_items].lang=(NULL!=lang?xmlStrdup(lang):NULL);
+            cp->keyword_array[cp->keyword_items].str=xmlStrndup(keywords+start, end-start);
+            cp->keyword_items++;
+        }
+        ofs++;
+    } while(keywords[ofs-1]!=0);
+}
+
+static void _opcCorePropertiesReadString(mceTextReader_t *r, xmlChar **v) {
+    mce_skip_attributes(r);
+    mce_start_children(r) {
+        mce_start_text(r) {
+            if (NULL!=v && NULL!=*v) xmlFree(*v);
+            *v=xmlStrdup(xmlTextReaderConstValue(r->reader));
+        } mce_end_text(r);
+    } mce_end_children(r);
+}
+
+static void _opcCorePropertiesReadSimpleType(mceTextReader_t *r, opcDCSimpleType_t *v) {
+    opc_bzero_mem(v, sizeof(*v));
+    mce_start_attributes(r) {
+        mce_start_attribute(r, _X(xml_ns), _X("lang")) {
+            if (NULL==v->lang) {
+                v->lang=xmlStrdup(xmlTextReaderConstValue(r->reader));
+            }
+        } mce_end_attribute(r);
+    } mce_end_attributes(r);
+    mce_start_children(r) {
+        mce_start_text(r) {
+            if (NULL==v->str) {
+                v->str=xmlStrdup(xmlTextReaderConstValue(r->reader));
+            }
+        } mce_end_text(r);
+    } mce_end_children(r);
+}
+
+opc_error_t opcCorePropertiesRead(opcProperties_t *cp, opcContainer *c) {
+    mceTextReader_t r;
+    if (OPC_ERROR_NONE==opcXmlReaderOpen(c, &r, _X("docProps/core.xml"), NULL, NULL, 0)) {
+            mce_start_document(&r) {
+                mce_start_element(&r, _X(cp_ns), _X("coreProperties")) {
+                    mce_skip_attributes(&r);
+                    mce_start_children(&r) {
+                        mce_start_element(&r, _X(cp_ns), _X("category")) {
+                            _opcCorePropertiesReadString(&r, &cp->category);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(cp_ns), _X("contentStatus")) {
+                            _opcCorePropertiesReadString(&r, &cp->contentStatus);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(dcterms_ns), _X("created")) {
+                            _opcCorePropertiesReadString(&r, &cp->created);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(dc_ns), _X("creator")) {
+                            _opcCorePropertiesReadSimpleType(&r, &cp->creator);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(dc_ns), _X("description")) {
+                            _opcCorePropertiesReadSimpleType(&r, &cp->description);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(dc_ns), _X("identifier")) {
+                            _opcCorePropertiesReadSimpleType(&r, &cp->identifier);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(cp_ns), _X("keywords")) {
+                            xmlChar *xml_lang=NULL;
+                            mce_start_attributes(&r) {
+                                mce_start_attribute(&r, _X(xml_ns), _X("lang")) {
+                                    xml_lang=xmlStrdup(xmlTextReaderConstValue(r.reader));
+                                } mce_end_attribute(&r);
+                            } mce_end_attributes(&r);
+                            mce_start_children(&r) {
+                                mce_start_element(&r, _X(cp_ns), _X("value")) {
+                                    xmlChar *value_xml_lang=NULL;
+                                    mce_start_attributes(&r) {
+                                        mce_start_attribute(&r, _X(xml_ns), _X("lang")) {
+                                            value_xml_lang=xmlStrdup(xmlTextReaderConstValue(r.reader));
+                                        } mce_end_attribute(&r);
+                                    } mce_end_attributes(&r);
+                                    mce_start_children(&r) {
+                                        mce_start_text(&r) {
+                                            _opcCorePropertiesAddKeywords(cp, xmlTextReaderConstValue(r.reader), value_xml_lang);
+                                        } mce_end_text(&r);
+                                    } mce_end_children(&r);
+                                if (NULL!=value_xml_lang) { xmlFree(value_xml_lang); value_xml_lang=NULL; };
+                                } mce_end_element(&r);
+                                mce_start_text(&r) {
+                                    _opcCorePropertiesAddKeywords(cp, xmlTextReaderConstValue(r.reader), xml_lang);
+                                } mce_end_text(&r);
+                            } mce_end_children(&r);
+                            if (NULL!=xml_lang) { xmlFree(xml_lang); xml_lang=NULL; };
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(dc_ns), _X("language")) {
+                            _opcCorePropertiesReadSimpleType(&r, &cp->language);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(cp_ns), _X("lastModifiedBy")) {
+                            _opcCorePropertiesReadString(&r, &cp->lastModifiedBy);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(cp_ns), _X("lastPrinted")) {
+                            _opcCorePropertiesReadString(&r, &cp->lastPrinted);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(dcterms_ns), _X("modified")) {
+                            _opcCorePropertiesReadString(&r, &cp->modified);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(cp_ns), _X("revision")) {
+                            _opcCorePropertiesReadString(&r, &cp->revision);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(dc_ns), _X("subject")) {
+                            _opcCorePropertiesReadSimpleType(&r, &cp->subject);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(dc_ns), _X("title")) {
+                            _opcCorePropertiesReadSimpleType(&r, &cp->title);
+                        } mce_end_element(&r);
+                        mce_start_element(&r, _X(cp_ns), _X("version")) {
+                            _opcCorePropertiesReadString(&r, &cp->version);
+                        } mce_end_element(&r);
+                    } mce_end_children(&r);
+                } mce_end_element(&r);
+            } mce_end_document(&r);
+        mceTextReaderCleanup(&r);
+    }
+    return OPC_ERROR_NONE;
+}
+
+static void _opcCorePropertiesWriteString(mceTextWriter *w, const xmlChar *ns, const xmlChar *name, const xmlChar *value, const xmlChar *type) {
+    if (NULL!=value) {
+        mceTextWriterStartElement(w, ns, name);
+        if (NULL!=type) {
+            mceTextWriterAttributeF(w, _X(xsi_ns), _X("type"), (const char *)type);
+        }
+        mceTextWriterWriteString(w, value);
+        mceTextWriterEndElement(w, ns, name);
+    }
+}
+
+static void _opcCorePropertiesWriteSimpleType(mceTextWriter *w, const xmlChar *ns, const xmlChar *name, const opcDCSimpleType_t*value) {
+    if (NULL!=value->str) {
+        mceTextWriterStartElement(w, ns, name);
+        if (NULL!=value->lang) {
+            mceTextWriterAttributeF(w, _X(xml_ns), _X("lang"), (const char *)value->lang);
+        }
+        mceTextWriterWriteString(w, value->str);
+        mceTextWriterEndElement(w, ns, name);
+    }
+}
+
+opc_error_t opcCorePropertiesWrite(opcProperties_t *cp, opcContainer *c) {
+    opcPart part=opcPartCreate(c, _X("docProps/core.xml"), _X("application/vnd.openxmlformats-package.core-properties+xml"), 0);
+    if (NULL!=part) {
+        mceTextWriter *w=mceTextWriterOpen(c, part, OPC_COMPRESSIONOPTION_SUPERFAST);
+        if (NULL!=w) {
+            mceTextWriterStartDocument(w);
+            mceTextWriterRegisterNamespace(w, _X(cp_ns), _X("cp"), MCE_DEFAULT);
+            mceTextWriterRegisterNamespace(w, _X(dc_ns), _X("dc"), MCE_DEFAULT);
+            mceTextWriterRegisterNamespace(w, _X(dcterms_ns), _X("dcterms"), MCE_DEFAULT);
+            mceTextWriterRegisterNamespace(w, _X(xsi_ns), _X("xsi"), MCE_DEFAULT);
+            mceTextWriterStartElement(w, _X(cp_ns), _X("coreProperties"));
+            _opcCorePropertiesWriteString(w, _X(cp_ns), _X("category"), cp->category, NULL);
+            _opcCorePropertiesWriteString(w, _X(cp_ns), _X("contentStatus"), cp->contentStatus, NULL);
+            _opcCorePropertiesWriteString(w, _X(dcterms_ns), _X("created"), cp->created, _X("dcterms:W3CDTF"));
+            _opcCorePropertiesWriteSimpleType(w, _X(dc_ns), _X("creator"), &cp->creator);
+            _opcCorePropertiesWriteSimpleType(w, _X(dc_ns), _X("description"), &cp->description);
+            _opcCorePropertiesWriteSimpleType(w, _X(dc_ns), _X("identifier"), &cp->identifier);
+            if (cp->keyword_items>0) {
+                mceTextWriterStartElement(w, _X(cp_ns), _X("keywords"));
+                for(opc_uint32_t i=0;i<cp->keyword_items;i++) {
+                    _opcCorePropertiesWriteSimpleType(w, _X(cp_ns), _X("value"), &cp->keyword_array[i]);
+                    if (i+1<cp->keyword_items) {
+                        mceTextWriterWriteString(w, _X(";"));
+                    }
+                }
+                mceTextWriterEndElement(w, _X(cp_ns), _X("keywords"));
+            }
+            _opcCorePropertiesWriteSimpleType(w, _X(dc_ns), _X("language"), &cp->language);
+            _opcCorePropertiesWriteString(w, _X(cp_ns), _X("lastModifiedBy"), cp->lastModifiedBy, NULL);
+            _opcCorePropertiesWriteString(w, _X(cp_ns), _X("lastPrinted"), cp->lastPrinted, _X("dcterms:W3CDTF"));
+            _opcCorePropertiesWriteString(w, _X(dcterms_ns), _X("modified"), cp->modified, _X("dcterms:W3CDTF"));
+            _opcCorePropertiesWriteString(w, _X(cp_ns), _X("revision"), cp->revision, NULL);
+            _opcCorePropertiesWriteSimpleType(w, _X(dc_ns), _X("subject"), &cp->subject);
+            _opcCorePropertiesWriteSimpleType(w, _X(dc_ns), _X("title"), &cp->title);
+            _opcCorePropertiesWriteString(w, _X(cp_ns), _X("version"), cp->version, NULL);
+            mceTextWriterEndElement(w, _X(cp_ns), _X("coreProperties"));
+            mceTextWriterEndDocument(w);
+            mceTextWriterFree(w);
+        }
+    }
+    return OPC_ERROR_NONE;
+}

+ 121 - 0
opc/properties.h

@@ -0,0 +1,121 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/properties.h
+ 
+ */
+#include <opc/config.h>
+#include <opc/container.h>
+
+#ifndef OPC_PROPERTIES_H
+#define OPC_PROPERTIES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+
+    /** 
+      Represents a simple Dublin Core type.
+      */
+    typedef struct OPC_DC_SIMPLE_TYPE {
+        xmlChar *str;
+        xmlChar *lang;
+    } opcDCSimpleType_t;
+
+    /** 
+      Represents the core properties of an OPC container.
+      */
+    typedef struct OPC_PROPERTIES_STRUCT {
+        xmlChar *category;                /* xsd:string     */
+        xmlChar *contentStatus;           /* xsd:string     */
+        xmlChar *created;                 /* dc:date        */
+        opcDCSimpleType_t creator;        /* dc:any         */
+        opcDCSimpleType_t description;    /* dc:any         */
+        opcDCSimpleType_t identifier;     /* dc:any         */
+        opcDCSimpleType_t *keyword_array; /* cp:CT_Keywords */
+        opc_uint32_t keyword_items;
+        opcDCSimpleType_t language;       /* dc:any         */
+        xmlChar *lastModifiedBy;          /* xsd:string     */
+        xmlChar *lastPrinted;             /* xsd:dateTime   */
+        xmlChar *modified;                /* dc:date        */
+        xmlChar *revision;                /* xsd:string     */
+        opcDCSimpleType_t subject;        /* dc:any         */
+        opcDCSimpleType_t title;          /* dc:any         */
+        xmlChar *version;                 /* xsd:string     */
+    } opcProperties_t;
+
+    /**
+      Initialize the core properties \c cp.
+      \see opcCorePropertiesSetString
+      */
+    opc_error_t opcCorePropertiesInit(opcProperties_t *cp);
+
+    /**
+      Cleanup the core properties \c cp, i.e. release all resources.
+      \see opcCorePropertiesSetString
+      */
+    opc_error_t opcCorePropertiesCleanup(opcProperties_t *cp);
+
+    /**
+      Rease the core properties \c cp from the container \c.
+      */
+    opc_error_t opcCorePropertiesRead(opcProperties_t *cp, opcContainer *c);
+
+
+    /**
+      Write/Update the core properties \c cp in the container \c.
+      */
+    opc_error_t opcCorePropertiesWrite(opcProperties_t *cp, opcContainer *c);
+
+    /**
+      Update a string in the core properties the right way.
+      \code
+      opcProperties_t cp;
+      opcCorePropertiesInit(&cp);
+      opcCorePropertiesSetString(&cp.revision, "1");
+      opcCorePropertiesSetStringLang(&cp.creator, "Florian Reuter", NULL);
+      opcCorePropertiesCleanup(&cp);
+      \endcode
+      */
+    opc_error_t opcCorePropertiesSetString(xmlChar **prop, const xmlChar *str);
+
+    /** 
+      Update a core properties the right way.
+      \see opcCorePropertiesSetString
+      */
+    opc_error_t opcCorePropertiesSetStringLang(opcDCSimpleType_t *prop, const xmlChar *str, const xmlChar *lang);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_PROPERTIES_H */

+ 153 - 0
opc/relation.c

@@ -0,0 +1,153 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+#include "internal.h"
+
+
+opcContainerRelation *opcContainerFindRelationByType(opcContainer *container, opcContainerRelation *relation_array, opc_uint32_t relation_items, const xmlChar *mimeType) {
+    for(opc_uint32_t i=0;i<relation_items;i++) {
+        if (0==xmlStrcmp(relation_array[i].relation_type, mimeType)) {
+            return &relation_array[i];
+        }
+    }
+    return NULL;
+}
+
+
+static opcContainerRelation* _opcRelationFind(opcContainer *container, opcPart part, opcRelation relation) {
+    if (OPC_PART_INVALID==part) {
+        return opcContainerFindRelation(container, container->relation_array, container->relation_items, relation);
+    } else {
+        opcContainerPart *cp=opcContainerInsertPart(container, part, OPC_FALSE);
+        return (cp!=NULL?opcContainerFindRelation(container, cp->relation_array, cp->relation_items, relation):NULL);
+    }
+}
+
+opcRelation opcRelationFind(opcContainer *container, opcPart part, const xmlChar *relationId, const xmlChar *mimeType) {
+    opcContainerRelation *rel=NULL;
+    if (OPC_PART_INVALID==part) {
+        if (NULL!=relationId) {
+            rel=opcContainerFindRelationById(container, container->relation_array, container->relation_items, relationId);
+        } else if (NULL!=mimeType) {
+            rel=opcContainerFindRelationByType(container, container->relation_array, container->relation_items, mimeType);
+        }
+    } else {
+        opcContainerPart *cp=opcContainerInsertPart(container, part, OPC_FALSE);
+        if (NULL!=cp) {
+            if (NULL!=relationId) {
+                rel=opcContainerFindRelationById(container, cp->relation_array, cp->relation_items, relationId);
+            } else if (NULL!=mimeType) {
+                rel=opcContainerFindRelationByType(container, cp->relation_array, cp->relation_items, mimeType);
+            }
+        }
+    }
+    return (NULL!=rel?rel->relation_id:OPC_RELATION_INVALID);
+}
+
+opcPart opcRelationGetInternalTarget(opcContainer *container, opcPart part, opcRelation relation) {
+    opcContainerRelation *rel=_opcRelationFind(container, part, relation);
+    if (rel!=NULL && 0==rel->target_mode) {
+        return (opcPart)rel->target_ptr;
+    } else {
+        return NULL;
+    }
+}
+
+const xmlChar *opcRelationGetExternalTarget(opcContainer *container, opcPart part, opcRelation relation) {
+    opcContainerRelation *rel=_opcRelationFind(container, part, relation);
+    if (rel!=NULL && 1==rel->target_mode) {
+        return rel->target_ptr;
+    } else {
+        return NULL;
+    }
+}
+
+opcRelation opcRelationFirst(opcContainer *container, opcPart part) {
+    if (OPC_PART_INVALID==part) {
+        return (container->relation_items>0?container->relation_array[0].relation_id:OPC_RELATION_INVALID);
+    } else {
+        opcContainerPart *cp=opcContainerInsertPart(container, part, OPC_FALSE);
+        return (NULL!=cp && cp->relation_items>0?cp->relation_array[0].relation_id:OPC_RELATION_INVALID);
+    }
+}
+
+opcRelation opcRelationNext(opcContainer *container, opcPart part, opcRelation relation) {
+    opcContainerRelation *relation_array=NULL;
+    opc_uint32_t relation_items=0;
+    if (OPC_PART_INVALID==part) {
+        relation_array=container->relation_array;
+        relation_items=container->relation_items;
+    } else {
+        opcContainerPart *cp=opcContainerInsertPart(container, part, OPC_FALSE);
+        if (NULL!=cp) {
+            relation_array=cp->relation_array;
+            relation_items=cp->relation_items;
+        }
+    }
+    if (relation_items>0) {
+        opcContainerRelation *rel=opcContainerFindRelation(container, relation_array, relation_items, relation);
+        if (rel+1<relation_array+relation_items) {
+            return (rel+1)->relation_id;
+        } else {
+            return OPC_RELATION_INVALID;
+        }
+    } else {
+        return OPC_RELATION_INVALID;
+    }
+}
+
+
+void opcRelationGetInformation(opcContainer *container, opcPart part, opcRelation relation, const xmlChar **prefix, opc_uint32_t *counter, const xmlChar **type) {
+    opcContainerRelation* rel=NULL;
+    if (NULL!=prefix) {
+        OPC_ASSERT(OPC_CONTAINER_RELID_PREFIX(relation)>=0 && OPC_CONTAINER_RELID_PREFIX(relation)<container->relprefix_items);
+        *prefix=container->relprefix_array[OPC_CONTAINER_RELID_PREFIX(relation)].prefix;
+    }
+    if (NULL!=counter) {
+        *counter=OPC_CONTAINER_RELID_COUNTER(relation);
+    }
+    
+    if (NULL!=type) {
+        if (NULL==rel) rel=_opcRelationFind(container, part, relation);
+        *type=(NULL!=rel?rel->relation_type:NULL);
+    }
+}
+
+opc_error_t opcRelationDelete(opcContainer *container, opcPart part, const xmlChar *relationId, const xmlChar *mimeType) {
+    opcRelation relation=opcRelationFind(container, part, relationId, mimeType);
+    if (OPC_PART_INVALID==part) {
+        return opcContainerDeleteRelation(container, &container->relation_array, &container->relation_items, relation);
+    } else {
+        opcContainerPart *cp=opcContainerInsertPart(container, part, OPC_FALSE);
+        return (cp!=NULL?opcContainerDeleteRelation(container, &cp->relation_array, &cp->relation_items, relation):OPC_ERROR_STREAM);
+    }
+}

+ 140 - 0
opc/relation.h

@@ -0,0 +1,140 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/relation.h
+ 
+ */
+#include <opc/config.h>
+
+#ifndef OPC_RELATION_H
+#define OPC_RELATION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+
+    /**
+     Indentifier for an OPC relation.
+     */
+    typedef opc_uint32_t opcRelation;
+
+/**
+  Constant which represents an invalid relation.
+*/
+#define OPC_RELATION_INVALID (-1)
+
+    /**
+      Find a relation originating from \c part in \c container with \c relationId and/or \c mimeType.
+      If \c part is OPC_PART_INVALID then part represents the root part.
+      @param[in] relationId The relationId (e.g. "rId1") or NULL.
+      @param[in] mimeType The mimeType or NULL.
+      */
+    opcRelation opcRelationFind(opcContainer *container, opcPart part, const xmlChar *relationId, const xmlChar *mimeType);
+
+    /**
+      Deleted the relation from the container.
+      \see opcRelationFind.
+      */
+    opc_error_t opcRelationDelete(opcContainer *container, opcPart part, const xmlChar *relationId, const xmlChar *mimeType);
+
+    /**
+      Returns the first relation.
+      The following code will dump all relations:
+      \code
+        for(opcPart part=opcPartGetFirst(c);OPC_PART_INVALID!=part;part=opcPartGetNext(c, part)) {
+           for(opcRelation rel=opcRelationFirst(part, c);
+               OPC_PART_INVALID!=rel;
+               rel=opcRelationNext(c, rel)) {
+               opcPart internal_target=opcRelationGetInternalTarget(c, part, rel);
+               const xmlChar *external_target=opcRelationGetExternalTarget(c, part, rel);
+               const xmlChar *target=(NULL!=internal_target?internal_target:external_target);
+               const xmlChar *prefix=NULL;
+               opc_uint32_t counter=-1;
+               const xmlChar *type=NULL;
+               opcRelationGetInformation(c, part, rel, &prefix, &counter, &type);        
+               if (-1==counter) { // no counter after prefix
+                  printf("%s;%s;%s;%s\n", part, prefix, target, type);
+               } else {
+                  printf("%s;%s%i;%s;%s\n", part, prefix, counter, target, type);
+               }
+           }
+        }
+      \endcode
+      */
+    opcRelation opcRelationFirst(opcContainer *container, opcPart part);
+
+    /**
+      \see opcRelationFirst
+      */
+    opcRelation opcRelationNext(opcContainer *container, opcPart part, opcRelation relation);
+    
+    /**
+      Returns the internal target.
+      \note To test for an external target use opcRelationGetExternalTarget.
+      \see opcRelationGetExternalTarget
+      */
+    opcPart opcRelationGetInternalTarget(opcContainer *container, opcPart part, opcRelation relation);
+
+    /**
+      Returns the external target or NULL if it is an internal target.
+      The string is interned. Must not be freed.
+      \see opcRelationGetExternalTarget
+      */
+    const xmlChar *opcRelationGetExternalTarget(opcContainer *container, opcPart part, opcRelation relation);
+
+    /**
+      Returns the relations type.
+      The string is interned. Must not be freed.
+      */
+    const xmlChar *opcRelationGetType(opcContainer *container, opcPart part, opcRelation relation);
+
+    /** 
+      Get information about a relation.
+      \see opcRelationFirst
+      */
+    void opcRelationGetInformation(opcContainer *container, opcPart part, opcRelation relation, const xmlChar **prefix, opc_uint32_t *counter, const xmlChar **type);
+
+    /** 
+      Add a relation to \c container from \c src part to \c dest part with id \c rid and type \c type.
+      */
+    opc_uint32_t opcRelationAdd(opcContainer *container, opcPart src, const xmlChar *rid, opcPart dest, const xmlChar *type);
+
+    /** 
+      Add an external relation to \c container from \c src part to \c target URL with id \c rid and type \c type.
+      */
+    opc_uint32_t opcRelationAddExternal(opcContainer *container, opcPart src, const xmlChar *rid, const xmlChar *target, const xmlChar *type);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+
+#endif /* OPC_RELATION_H */

+ 65 - 0
opc/xmlreader.c

@@ -0,0 +1,65 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+#include "internal.h"
+
+opc_error_t opcXmlReaderOpenEx(opcContainer *container, mceTextReader_t *mceTextReader, const xmlChar *partName, opc_bool_t rels_segment, const char * URL, const char * encoding, int options) {
+    opcContainerInputStream* stream=opcContainerOpenInputStreamEx(container, partName, rels_segment);
+    if (NULL!=stream) {
+        if (0==mceTextReaderInit(mceTextReader, 
+                                 xmlReaderForIO((xmlInputReadCallback)opcContainerReadInputStream, 
+                                                (xmlInputCloseCallback)opcContainerCloseInputStream, 
+                                                stream, URL, encoding, options))) {
+            return OPC_ERROR_NONE;
+        } else {
+            return OPC_ERROR_STREAM;
+        }
+    } else {
+        return OPC_ERROR_STREAM;
+    }
+}
+
+opc_error_t opcXmlReaderOpen(opcContainer *container, mceTextReader_t *mceTextReader, const xmlChar *partName, const char * URL, const char * encoding, int options) {
+    return opcXmlReaderOpenEx(container, mceTextReader, (partName!=NULL && partName[0]=='/'?partName+1:partName), OPC_FALSE, URL, encoding, options);
+}
+
+xmlDocPtr opcXmlReaderReadDoc(opcContainer *container, const xmlChar *partName, const char * URL, const char * encoding, int options) {
+    opcContainerInputStream* stream=opcContainerOpenInputStreamEx(container, partName, OPC_FALSE);
+    if (NULL!=stream) {
+        xmlDocPtr doc=xmlReadIO((xmlInputReadCallback)opcContainerReadInputStream, 
+                                (xmlInputCloseCallback)opcContainerCloseInputStream, 
+                                stream, URL, encoding, options);
+        return doc;
+    } else {
+        return NULL;
+    }
+}

+ 69 - 0
opc/xmlreader.h

@@ -0,0 +1,69 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/xmlreader.h
+ 
+ */
+
+#ifndef OPC_XMLREADER_H
+#define OPC_XMLREADER_H
+
+#include <opc/config.h>
+#include <libxml/xmlreader.h>
+#include <mce/textreader.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+
+    /** 
+      Open an MCE reader for \c partName. Parameters \c URL, \c encoding and \c options will be passed unmodified to 
+      http://xmlsoft.org/html/libxml-xmlreader.html#xmlReaderForIO and they can we NULL, NULL, 0.
+      \note Make sure the part exists.
+      \see opcPartFind
+      */
+    opc_error_t opcXmlReaderOpen(opcContainer *container, mceTextReader_t *mceTextReader, const xmlChar *partName, const char * URL, const char * encoding, int options);
+
+    /**
+      Returns an libxml DOM document. Parameters \c URL, \c encoding and \c options will be passed unmodified to 
+      http://xmlsoft.org/html/libxml-parser.html#xmlReadIO and they can we NULL, NULL, 0.
+      \note Make sure the part exists.
+      \see opcPartFind
+      */
+    xmlDocPtr opcXmlReaderReadDoc(opcContainer *container, const xmlChar *partName, const char * URL, const char * encoding, int options);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_XMLREADER_H */

+ 53 - 0
opc/xmlwriter.c

@@ -0,0 +1,53 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+#include <mce/textreader.h>
+
+
+static int opcTextWriterWrite(void * context, const char * buffer, int len) {
+    opcContainerOutputStream *stream=(opcContainerOutputStream *)context;
+    return opcContainerWriteOutputStream(stream, (const opc_uint8_t*)buffer, len);
+}
+
+static int opcTextWriterClose(void * context) {
+    opcContainerOutputStream *stream=(opcContainerOutputStream *)context;
+    return (OPC_ERROR_NONE==opcContainerCloseOutputStream(stream)?0:-1);
+}
+
+mceTextWriter *mceTextWriterOpen(opcContainer *c, opcPart part, opcCompressionOption_t compression_option) {
+    opcContainerOutputStream *stream=opcContainerCreateOutputStream(c, part, compression_option);
+    mceTextWriter *w=NULL;
+    if (NULL!=stream) {
+        w=mceTextWriterCreateIO(opcTextWriterWrite, opcTextWriterClose, stream, NULL);
+    }
+    return w;
+}

+ 57 - 0
opc/xmlwriter.h

@@ -0,0 +1,57 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/xmlwriter.h
+ 
+ */
+#include <opc/config.h>
+#include <mce/textwriter.h>
+
+#ifndef OPC_XMLWRITER_H
+#define OPC_XMLWRITER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+
+    /**
+      Create an MCE text writer for \c part in \c container with compression \c compression_option.
+      \note Make sure the part exists.
+      \see opcPartFind
+      */
+    mceTextWriter *mceTextWriterOpen(opcContainer *c, opcPart part, opcCompressionOption_t compression_option);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_XMLWRITER_H */

+ 1498 - 0
opc/zip.c

@@ -0,0 +1,1498 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+#include <opc/helper.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/globals.h>
+#include <string.h>
+#include <stdio.h>
+#include "internal.h"
+
+static void* ensureItem(void **array_, puint32_t items, puint32_t item_size) {
+    *array_=xmlRealloc(*array_, (items+1)*item_size);
+    return *array_;
+}
+
+static opcZipSegment* ensureSegment(opcZip *zip) {
+    return ((opcZipSegment*)ensureItem((void**)&zip->segment_array, zip->segment_items, sizeof(opcZipSegment)))+zip->segment_items;
+}
+
+
+static inline opc_uint32_t _opcZipFileRead(opcIO_t *io, opc_uint8_t *buf, opc_uint32_t buf_len) {
+    OPC_ASSERT(NULL!=io && io->_ioread!=NULL && NULL!=buf);
+    opc_uint32_t ret=0;
+    if (OPC_ERROR_NONE==io->state.err) {
+        int len=io->_ioread(io->iocontext, (char *)buf, buf_len);
+        if (ret<0) {
+            io->state.err=OPC_ERROR_STREAM;
+        } else {
+            ret=(opc_uint32_t)len;
+            io->state.buf_pos+=ret;
+        }
+    }
+    return ret;
+}
+
+static inline opc_uint32_t _opcZipFileWrite(opcIO_t *io, const opc_uint8_t *buf, opc_uint32_t buf_len) {
+    OPC_ASSERT(NULL!=io && io->_iowrite!=NULL && NULL!=buf);
+    opc_uint32_t ret=0;
+    if (OPC_ERROR_NONE==io->state.err) {
+        int len=io->_iowrite(io->iocontext, (const char *)buf, buf_len);
+        if (ret<0) {
+            io->state.err=OPC_ERROR_STREAM;
+        } else {
+            ret=(opc_uint32_t)len;
+            io->state.buf_pos+=ret;
+            if (io->state.buf_pos>io->file_size) io->file_size=io->state.buf_pos;
+        }
+    }
+    return ret;
+}
+
+static inline opc_error_t _opcZipFileClose(opcIO_t *io) {
+    OPC_ASSERT(NULL!=io && io->_ioclose!=NULL);
+    if (0!=io->_ioclose(io->iocontext)) {
+        if (OPC_ERROR_NONE==io->state.err) {
+            io->state.err=OPC_ERROR_STREAM;
+        }
+    }
+    return io->state.err;
+}
+
+static inline opc_ofs_t _opcZipFileSeek(opcIO_t *io, opc_ofs_t ofs, opcFileSeekMode whence) {
+    OPC_ASSERT(NULL!=io && (opcFileSeekSet==whence || opcFileSeekCur==whence || opcFileSeekEnd==whence));
+    opc_ofs_t abs=io->state.buf_pos;
+    if (OPC_ERROR_NONE==io->state.err) {
+        switch (whence) {
+        case opcFileSeekSet: abs=ofs; break;
+        case opcFileSeekCur: abs+=ofs; break;
+        case opcFileSeekEnd: abs=io->file_size-ofs; break;
+        }
+        if (abs<0 || abs>io->file_size) {
+            io->state.err=OPC_ERROR_STREAM;
+        } else if (io->state.buf_pos!=abs) {
+            if (NULL!=io->_ioseek) {
+                int _ofs=io->_ioseek(io->iocontext, abs);
+                if (_ofs!=abs) {
+                    io->state.err=OPC_ERROR_STREAM;
+                } else {
+                    io->state.buf_pos=abs;
+                }
+            } else {
+                io->state.err=OPC_ERROR_SEEK;
+            }
+        }
+    }
+    return abs;
+}
+
+static inline opc_error_t _opcZipFileGrow(opcIO_t *io, opc_uint32_t abs) {
+    if (OPC_ERROR_NONE==io->state.err) {
+        if (abs>io->file_size) {
+            io->file_size=abs; //@TODO add error handling here if e.g. file can not grow because disk is full etc...
+        }
+    }
+    return io->state.err;
+}
+
+
+opc_error_t _opcZipFileMove(opcIO_t *io, opc_ofs_t dest, opc_ofs_t src, opc_ofs_t len) {
+    opc_uint8_t buf[1024];
+    while(len>0) {
+        opc_ofs_t delta=(dest<src?src-dest:dest-src);
+        opc_uint32_t chunk=(delta>sizeof(buf)?(opc_uint32_t)sizeof(buf):(opc_uint32_t)delta);
+        if (chunk>len) chunk=len;
+        OPC_ENSURE(src==_opcZipFileSeek(io, src, opcFileSeekSet));
+        OPC_ENSURE(chunk==_opcZipFileRead(io, buf, chunk));
+        OPC_ENSURE(dest==_opcZipFileSeek(io, dest, opcFileSeekSet));
+        OPC_ENSURE(chunk==_opcZipFileWrite(io, buf, chunk));
+        OPC_ASSERT(chunk<=len);
+        len-=chunk;
+        dest+=chunk;
+        src+=chunk;
+    }
+    OPC_ASSERT(0==len);
+    return io->state.err;
+}
+
+opc_error_t _opcZipFileTrim(opcIO_t *io, opc_ofs_t new_size) {
+    OPC_ASSERT(new_size<=io->file_size);
+    int ret=(NULL!=io->_iotrim?io->_iotrim(io->iocontext, new_size):-1);
+    return (0==ret?OPC_ERROR_NONE:OPC_ERROR_STREAM);
+}
+
+opc_error_t _opcZipFileFlush(opcIO_t *io) {
+    int ret=(NULL!=io->_ioflush?io->_ioflush(io->iocontext):-1);
+    return (0==ret?OPC_ERROR_NONE:OPC_ERROR_STREAM);
+}
+
+opcZip *opcZipCreate(opcIO_t *io) {
+    opcZip *zip=(opcZip*)xmlMalloc(sizeof(opcZip));
+    if (NULL!=zip) {
+        memset(zip, 0, sizeof(*zip));
+        zip->first_free_segment_id=-1;
+        zip->io=io; 
+    }
+    return zip;
+}
+
+
+void opcZipClose(opcZip *zip, opcZipSegmentReleaseCallback* releaseCallback) {
+    if (NULL!=zip) {
+        if (NULL!=releaseCallback) {
+            for(opc_uint32_t i=0;i<zip->segment_items;i++) {
+                if (!zip->segment_array[i].deleted_segment) {
+                    releaseCallback(zip, i);
+                }
+            }
+        }
+        OPC_ASSERT(NULL!=zip->io->_ioclose);
+        OPC_ENSURE(0==zip->io->_ioclose(zip->io->iocontext));
+        if (NULL!=zip->segment_array) {
+            xmlFree(zip->segment_array);
+            zip->segment_array=NULL;
+        }
+        xmlFree(zip);
+    }
+}
+
+
+
+static inline opc_error_t _opcZipFileSeekRawState(opcIO_t *io, opcFileRawState *rawState, puint32_t new_ofs) {
+    if (OPC_ERROR_NONE==rawState->err) {
+        rawState->err=io->state.err;
+    }
+    if (OPC_ERROR_NONE==rawState->err) {
+        if (_opcZipFileSeek(io, new_ofs, opcFileSeekSet)!=new_ofs) {
+            *rawState=io->state; // indicate an error
+        } else {
+            rawState->buf_pos=new_ofs; // all OK
+        }
+    }
+    return rawState->err;
+}
+
+static inline opc_uint32_t opcZipRawWrite(opcIO_t *io, opcFileRawState *raw, const opc_uint8_t *buffer, opc_uint32_t len) {
+    opc_uint32_t ret=0;
+    if (OPC_ERROR_NONE==raw->err) {
+        if (OPC_ERROR_NONE==io->state.err) {
+            if (raw->buf_pos==io->state.buf_pos) {
+                ret=_opcZipFileWrite(io, buffer, len);
+                *raw=io->state;
+            } else {
+                raw->err=OPC_ERROR_SEEK;
+            }
+        } else {
+            *raw=io->state;
+        }
+    }
+    return ret;
+}
+
+static inline opc_error_t opcZipInitRawState(opcIO_t *io, opcFileRawState *rawState) {
+    *rawState=io->state;
+    return rawState->err;
+}
+
+
+static inline int opcZipRawWriteU8(opcIO_t *io, opcFileRawState *raw, opc_uint8_t val) {
+    return opcZipRawWrite(io, raw, (const opc_uint8_t *)&val, sizeof(opc_uint8_t));
+}
+
+static inline int opcZipRawWrite8(opcIO_t *io, opcFileRawState *raw, opc_int8_t val) {
+    return opcZipRawWriteU8(io, raw, (opc_uint8_t)val);
+}
+
+static inline int opcZipRawWriteZero(opcIO_t *io, opcFileRawState *raw, opc_uint32_t count) {
+    int ret=0;
+    opc_uint8_t val=0;
+    //@TODO may speed me up a bit (using fappend...)
+    for(opc_uint32_t i=0;i<count;i++) {
+        ret+=opcZipRawWriteU8(io, raw, val);
+    }
+    return ret;
+}
+
+
+static inline int opcZipRawWriteU16(opcIO_t *io, opcFileRawState *raw, opc_uint16_t val) {
+    int i=0;
+    while(OPC_ERROR_NONE==raw->err && i<sizeof(val) && 1==opcZipRawWriteU8(io, raw, (opc_uint8_t)(((unsigned)val)>>(i<<3)))) {
+        i++;
+    }
+    return i;
+}
+
+static inline int opcZipRawWriteU32(opcIO_t *io, opcFileRawState *raw, opc_uint32_t val) {
+    int i=0;
+    while(OPC_ERROR_NONE==raw->err && i<sizeof(val) && 1==opcZipRawWriteU8(io, raw, (opc_uint8_t)(((unsigned)val)>>(i<<3)))) {
+        i++;
+    }
+    return i;
+}
+
+
+static opc_error_t opcZipInitRawBuffer(opcIO_t *io, opcFileRawBuffer *rawBuffer) {
+    opc_bzero_mem(rawBuffer, sizeof(*rawBuffer));
+    return opcZipInitRawState(io, &rawBuffer->state);;
+}
+
+static inline opc_uint16_t opcZipCalculateHeaderSize(const char *name8, opc_uint16_t name8_len, opc_bool_t extra, opc_uint16_t *name8_max) {
+    opc_uint16_t len=(NULL!=name8_max?*name8_max:name8_len);
+    return 4*4+7*2+(extra?4*2:0)+len;
+}
+
+static opc_uint32_t opcZipRawWriteSegmentHeaderEx(opcIO_t *io, 
+                                                  opcFileRawState *rawState, 
+                                                  const char *name8, opc_uint16_t name8_len,
+                                                  opc_uint16_t bit_flag,
+                                                  opc_uint32_t crc32,
+                                                  opc_uint16_t compression_method,
+                                                  opc_ofs_t compressed_size,
+                                                  opc_ofs_t uncompressed_size,
+                                                  opc_uint16_t header_size,
+                                                  opc_uint16_t growth_hint) {
+    opc_uint32_t ret=0;
+    OPC_ASSERT(opcZipCalculateHeaderSize(name8, name8_len, OPC_FALSE, NULL)<=header_size);
+    opc_bool_t extra=opcZipCalculateHeaderSize(name8, name8_len, OPC_TRUE, NULL)<=header_size;
+    if (opcZipCalculateHeaderSize(name8, name8_len, extra, NULL)<=header_size) {
+        opc_uint16_t padding=(extra?header_size-opcZipCalculateHeaderSize(name8, name8_len, extra, NULL):0);
+        OPC_ASSERT(padding==0 || extra); // padding!=0 implies extra... you need the extra header to be able to add padding!
+        if ((4==(ret+=opcZipRawWriteU32(io, rawState, 0x04034b50)))
+        && (6==(ret+=opcZipRawWriteU16(io, rawState, 20)))  //version needed to extract
+        && (8==(ret+=opcZipRawWriteU16(io, rawState, bit_flag)))  // bit flag
+        && (10==(ret+=opcZipRawWriteU16(io, rawState, compression_method)))  // compression method
+        && (12==(ret+=opcZipRawWriteU16(io, rawState, 0x0)))  // last mod file time
+        && (14==(ret+=opcZipRawWriteU16(io, rawState, 0x0)))  // last mod file date
+        && (18==(ret+=opcZipRawWriteU32(io, rawState, crc32)))  // crc32
+        && (22==(ret+=opcZipRawWriteU32(io, rawState, compressed_size)))  // compressed size
+        && (26==(ret+=opcZipRawWriteU32(io, rawState, uncompressed_size)))  // uncompressed size
+        && (28==(ret+=opcZipRawWriteU16(io, rawState, name8_len)))  // filename length
+        && (30==(ret+=opcZipRawWriteU16(io, rawState, (extra?4*2+padding:0))))  // extra length
+        && (30+name8_len==(ret+=opcZipRawWrite(io, rawState, (opc_uint8_t *)name8, name8_len)))
+        && (!extra || 32+name8_len==(ret+=opcZipRawWriteU16(io, rawState, 0xa220)))  // extra: Microsoft Open Packaging Growth Hint
+        && (!extra || 34+name8_len==(ret+=opcZipRawWriteU16(io, rawState, 2+2+padding)))  // extra: size of Sig + PadVal + Padding
+        && (!extra || 36+name8_len==(ret+=opcZipRawWriteU16(io, rawState, 0xa028)))  // extra: verification signature (A028)
+        && (!extra || 38+name8_len==(ret+=opcZipRawWriteU16(io, rawState, growth_hint)))  // extra: Initial padding value
+        && (!extra || 38+name8_len+padding==(ret+=opcZipRawWriteZero(io, rawState, padding)))) { // extra: filled with NULL characters
+            OPC_ASSERT(opcZipCalculateHeaderSize(name8, name8_len, extra, NULL)+padding==ret);
+        }
+        return (opcZipCalculateHeaderSize(name8, name8_len, extra, NULL)+padding==ret?ret:0);
+    } else {
+        return 0; // no enough space to write header!
+    }
+}
+
+static opc_error_t opcZipRawWriteCentralDirectoryEx(opcIO_t *io, 
+                                                  opcFileRawState *rawState, 
+                                                  const char *name8, opc_uint16_t name8_len,
+                                                  opc_uint16_t bit_flag,
+                                                  opc_uint32_t crc32,
+                                                  opc_uint16_t compression_method,
+                                                  opc_ofs_t compressed_size,
+                                                  opc_ofs_t uncompressed_size,
+                                                  opc_uint16_t header_size,
+                                                  opc_uint16_t growth_hint,
+                                                  opc_ofs_t stream_ofs) {
+    if (OPC_ERROR_NONE==rawState->err) {
+        if((4==opcZipRawWriteU32(io, rawState, 0x02014b50))
+        && (2==opcZipRawWriteU16(io, rawState, 20))  // version made by 
+        && (2==opcZipRawWriteU16(io, rawState, 20))  // version needed to extract
+        && (2==opcZipRawWriteU16(io, rawState, bit_flag))  // bit flag
+        && (2==opcZipRawWriteU16(io, rawState, compression_method))  // compression method
+        && (2==opcZipRawWriteU16(io, rawState, 0x0))  // last mod file time
+        && (2==opcZipRawWriteU16(io, rawState, 0x0))  // last mod file date
+        && (4==opcZipRawWriteU32(io, rawState, crc32))  // crc32
+        && (4==opcZipRawWriteU32(io, rawState, compressed_size))  // compressed size
+        && (4==opcZipRawWriteU32(io, rawState, uncompressed_size))  // uncompressed size
+        && (2==opcZipRawWriteU16(io, rawState, name8_len))  // filename length
+        && (2==opcZipRawWriteU16(io, rawState, 0x0))  // extra length
+        && (2==opcZipRawWriteU16(io, rawState, 0x0))  // comment length
+        && (2==opcZipRawWriteU16(io, rawState, 0x0))  // disk number start
+        && (2==opcZipRawWriteU16(io, rawState, 0x0))  // internal file attributes
+        && (4==opcZipRawWriteU32(io, rawState, 0x0))  // external file attributes
+        && (4==opcZipRawWriteU32(io, rawState, stream_ofs))  // relative offset of local header
+        && (name8_len==opcZipRawWrite(io, rawState, (opc_uint8_t*)name8, name8_len))) {
+
+        } else {
+            rawState->err=OPC_ERROR_STREAM;
+        }
+    }
+    return rawState->err;
+}
+
+
+static opc_error_t opcZipRawWriteEndOfCentralDirectoryEx(opcIO_t *io, 
+                                                  opcFileRawState *rawState,
+                                                  opc_ofs_t central_dir_start_ofs, 
+                                                  opc_uint32_t segments) {
+    opc_ofs_t central_dir_end_ofs=rawState->buf_pos;
+    OPC_ASSERT(central_dir_start_ofs<=central_dir_end_ofs);
+    if (OPC_ERROR_NONE==rawState->err) {
+        if((4==opcZipRawWriteU32(io, rawState, 0x06054b50))
+        && (2==opcZipRawWriteU16(io, rawState, 0x0))  // number of this disk
+        && (2==opcZipRawWriteU16(io, rawState, 0x0))  // number of the disk with the start of the central directory
+        && (2==opcZipRawWriteU16(io, rawState, segments))  // total number of entries in the central directory on this disk
+        && (2==opcZipRawWriteU16(io, rawState, segments))  // total number of entries in the central directory 
+        && (4==opcZipRawWriteU32(io, rawState, central_dir_end_ofs-central_dir_start_ofs))  // size of the central directory
+        && (4==opcZipRawWriteU32(io, rawState, central_dir_start_ofs))  // offset of start of central directory with respect to the starting disk number
+        && (2==opcZipRawWriteU16(io, rawState, 0x0))) {// .ZIP file comment length
+
+        } else {
+            rawState->err=OPC_ERROR_STREAM;
+        }
+    }
+    return rawState->err;
+}
+
+
+static inline int opcZipRawReadBuffer(opcIO_t *io, opcFileRawBuffer *raw, opc_uint8_t *buffer, opc_uint32_t buf_len) {
+    OPC_ASSERT(NULL!=raw);
+    OPC_ASSERT(OPC_ERROR_NONE!=raw->state.err || raw->buf_ofs<=raw->buf_len);
+    opc_uint32_t buf_ofs=0;
+    while(OPC_ERROR_NONE==raw->state.err && buf_ofs<buf_len) {
+        opc_uint32_t req_size=buf_len-buf_ofs;
+        if (raw->buf_ofs<raw->buf_len) {
+            opc_uint32_t size=raw->buf_len-raw->buf_ofs;
+            if (size>req_size) size=req_size;
+            memcpy(buffer+buf_ofs, raw->buf+raw->buf_ofs, size);
+            raw->buf_ofs+=size;
+            buf_ofs+=size;
+            raw->state.buf_pos+=size;
+        } else {
+            OPC_ASSERT(raw->buf_ofs==raw->buf_len);
+            int ret=_opcZipFileRead(io, buffer+buf_ofs, req_size);
+            if (0==ret) {
+                buf_len=0; // causes the loop to exit
+            } else if (ret<0) {
+                raw->state.err=OPC_ERROR_STREAM;
+            } else {
+                buf_ofs+=ret;
+                raw->state.buf_pos+=ret;
+            }
+        }
+    }
+    return buf_ofs;
+}
+
+
+
+static inline opc_uint32_t opcZipRawPeekHeaderSignature(opcIO_t *io, opcFileRawBuffer *raw) {
+    OPC_ASSERT(NULL!=io && NULL!=raw);
+    if (OPC_ERROR_NONE==raw->state.err && raw->buf_ofs+4>raw->buf_len) {
+        // less than four bytes available...
+        if (raw->buf_ofs>0) { // move the bytes to the beginning
+            opc_uint32_t delta=raw->buf_len-raw->buf_ofs;
+            OPC_ASSERT(delta<=4);
+            for(opc_uint32_t i=0;i<delta;i++) {
+                raw->buf[i]=raw->buf[i+raw->buf_ofs];
+            }
+            raw->buf_len-=raw->buf_ofs;
+            raw->buf_ofs=0;
+        }
+        // fill the remaining buffer
+        OPC_ASSERT(0==raw->buf_ofs && raw->buf_len<sizeof(raw->buf));
+        int ret=_opcZipFileRead(io, raw->buf+raw->buf_len, (sizeof(raw->buf)-raw->buf_len));
+        if (ret<0) {
+            raw->state.err=OPC_ERROR_STREAM;
+        } else {
+            raw->buf_len+=ret;
+        }
+        OPC_ASSERT(0==raw->buf_ofs && raw->buf_len<=sizeof(raw->buf));
+    }
+    if (OPC_ERROR_NONE==raw->state.err && 0==raw->buf_len) {
+        return 0; // end of file
+    } else if (OPC_ERROR_NONE!=raw->state.err || raw->buf_ofs+4>raw->buf_len) { 
+        // either an error or not enough bytes
+        return -1;
+    } else { 
+        OPC_ASSERT(OPC_ERROR_NONE==raw->state.err && raw->buf_ofs+4<=raw->buf_len); // enough bytes...
+        return (raw->buf[raw->buf_ofs]<<0)
+              +(raw->buf[raw->buf_ofs+1]<<8)
+              +(raw->buf[raw->buf_ofs+2]<<16)
+              +(raw->buf[raw->buf_ofs+3]<<24);
+    }
+}
+
+static inline opc_error_t opcZipRawFill(opcIO_t *io, opcFileRawBuffer *raw, opc_uint32_t max) {
+    OPC_ASSERT(OPC_ERROR_NONE!=raw->state.err || raw->buf_ofs<=raw->buf_len);
+    if (OPC_ERROR_NONE==raw->state.err && raw->buf_ofs==raw->buf_len) {
+        opc_uint32_t const len=(sizeof(raw->buf)<max?sizeof(raw->buf):max);
+        int ret=_opcZipFileRead(io, raw->buf, len);
+        if (ret<0) {
+            raw->state.err=OPC_ERROR_STREAM;
+            raw->buf_len=0;
+        } else {
+            raw->buf_len=ret;
+        }
+        raw->buf_ofs=0;
+    }
+    OPC_ASSERT(OPC_ERROR_NONE==raw->state.err || 0==raw->buf_len || raw->buf_ofs<raw->buf_len);
+    return raw->state.err;
+}
+
+static inline opc_uint32_t opcZipRawInflateBuffer(opcIO_t *io, opcFileRawBuffer *raw, opcZipInflateState *state, opc_uint8_t *buffer, opc_uint32_t buf_len) {
+    OPC_ASSERT(NULL!=raw);
+    OPC_ASSERT(OPC_ERROR_NONE!=raw->state.err || raw->buf_ofs<=raw->buf_len);
+    opc_uint32_t buf_ofs=0;
+    while(OPC_ERROR_NONE==raw->state.err &&  Z_OK==state->inflate_state && buf_ofs<buf_len) {
+        int const max_stream=state->compressed_size-state->stream.total_in;
+        if (OPC_ERROR_NONE==opcZipRawFill(io, raw, max_stream)) {
+            state->stream.next_in=raw->buf+raw->buf_ofs;
+            state->stream.avail_in=raw->buf_len-raw->buf_ofs;
+            state->stream.next_out=buffer+buf_ofs;
+            state->stream.avail_out=buf_len-buf_ofs;
+            if (Z_OK==(state->inflate_state=inflate(&state->stream, Z_SYNC_FLUSH)) || Z_STREAM_END==state->inflate_state) {
+                opc_uint32_t const consumed_in=raw->buf_len-raw->buf_ofs-state->stream.avail_in;
+                opc_uint32_t const consumed_out=buf_len-buf_ofs-state->stream.avail_out;
+                raw->buf_ofs+=consumed_in;
+                raw->state.buf_pos+=consumed_in;
+                buf_ofs+=consumed_out;
+                if (0==consumed_out && 0==consumed_in) {
+                    raw->state.err=OPC_ERROR_DEFLATE; // protect us from an endless loop. shlould not happen
+                }
+            } else {
+                raw->state.err=OPC_ERROR_DEFLATE;
+            }
+        }
+    }
+    return buf_ofs;
+}
+
+
+static inline int opcZipRawReadU8(opcIO_t *io, opcFileRawBuffer *raw, opc_uint8_t *val) {
+    OPC_ASSERT(NULL!=raw);
+    opcZipRawFill(io, raw, -1);
+    OPC_ASSERT(OPC_ERROR_NONE==raw->state.err || 0==raw->buf_len || raw->buf_ofs<raw->buf_len);
+    if (OPC_ERROR_NONE!=raw->state.err) {
+        if (NULL!=val) {
+            *val=-1;
+        }
+        return -1;
+    } else if (0==raw->buf_len) {
+        if (NULL!=val) {
+            *val=0;
+        }
+        return 0;
+    } else {
+        if (NULL!=val) {
+            *val=raw->buf[raw->buf_ofs];
+        }
+        raw->buf_ofs++;
+        raw->state.buf_pos++;
+        return 1;
+    }
+}
+
+static inline int opcZipRawRead8(opcIO_t *io, opcFileRawBuffer *raw, opc_int8_t *val) {
+    return opcZipRawReadU8(io, raw, (opc_uint8_t*)val);
+}
+
+#define OPC_READ_LITTLE_ENDIAN(io, raw, type, val) \
+    opc_uint8_t aux;\
+    int ret;\
+    int i=0;\
+    if (NULL!=val) {\
+        *val=0;\
+    }\
+    while(i<sizeof(type) && (1==(ret=opcZipRawReadU8(io, raw, &aux)))) {\
+        if (NULL!=val) {\
+            *val|=((type)aux)<<(i<<3);\
+        }\
+        i++;\
+    }\
+    return (i==sizeof(type)?i:ret);\
+
+static inline int opcZipRawReadU16(opcIO_t *io, opcFileRawBuffer *raw, opc_uint16_t *val) {
+    OPC_READ_LITTLE_ENDIAN(io, raw, opc_uint16_t, val);
+}
+
+static inline int opcZipRawRead16(opcIO_t *io, opcFileRawBuffer *raw, opc_int16_t *val) {
+    OPC_READ_LITTLE_ENDIAN(io, raw, opc_int16_t, val);
+}
+
+static inline int opcZipRawReadU32(opcIO_t *io, opcFileRawBuffer *raw, opc_uint32_t *val) {
+    OPC_READ_LITTLE_ENDIAN(io, raw, opc_uint32_t, val);
+}
+
+static inline int opcZipRawRead32(opcIO_t *io, opcFileRawBuffer *raw, opc_int32_t *val) {
+    OPC_READ_LITTLE_ENDIAN(io, raw, opc_int32_t, val);
+}
+
+static inline int opcZipRawReadU64(opcIO_t *io, opcFileRawBuffer *raw, opc_uint64_t *val) {
+    OPC_READ_LITTLE_ENDIAN(io, raw, opc_uint64_t, val);
+}
+
+static inline int opcZipRawRead64(opcIO_t *io, opcFileRawBuffer *raw, opc_int64_t *val) {
+    OPC_READ_LITTLE_ENDIAN(io, raw, opc_int64_t, val);
+}
+
+static inline int opcZipRawSkipBytes(opcIO_t *io, opcFileRawBuffer *raw, opc_uint32_t len) {
+    if (OPC_ERROR_NONE!=raw->state.err) {
+        return 0;
+    } else {
+        //@TODO speed me up! when seek is available
+        int ret=0;
+        opc_uint32_t i=0;
+        opc_uint8_t val;
+        while(i<len && (1==(ret=opcZipRawReadU8(io, raw, &val)))) i++;
+        return (i==len?i:ret);
+    }
+}
+
+static inline int opcZipRawReadString(opcIO_t *io, opcFileRawBuffer *raw, xmlChar *str, opc_uint32_t str_len, opc_uint32_t str_max) {
+    opc_uint32_t str_ofs=0;
+    opc_uint32_t flag=1;
+    while(OPC_ERROR_NONE==raw->state.err && str_ofs<str_len && str_ofs+1<str_max && flag>0) {
+        opc_uint8_t ch=0;
+        if (1==(flag=opcZipRawReadU8(io, raw, &ch))) {
+            if ('%'==ch) {
+                opc_uint8_t hex1=0;
+                opc_uint8_t hex2=0;
+                if (1==(flag=opcZipRawReadU8(io, raw, &hex1)) && 1==(flag=opcZipRawReadU8(io, raw, &hex2))) {
+                    opc_uint32_t hi=0;
+                    if (hex1>='0' && hex1<='9') hi=hex1-'0';
+                    else if (hex1>='A' && hex1<='F') hi=hex1-'A'+10;
+                    else if (hex1>='a' && hex1<='f') hi=hex1-'a'+10;
+                    else flag=0; // error
+                    opc_uint32_t low=0;
+                    if (hex1>='0' && hex1<='9') low=hex1-'0';
+                    else if (hex1>='A' && hex1<='F') low=hex1-'A'+10;
+                    else if (hex1>='a' && hex1<='f') low=hex1-'a'+10;
+                    else flag=0; // error
+                    if (flag) {
+                        str[str_ofs++]=hi*16+low;
+                    }
+                }
+            } else {
+                str[str_ofs++]=ch;
+            }
+        }
+    }
+    OPC_ASSERT(str_ofs+1<str_max);
+    str[str_ofs]=0; // terminate string
+    return str_ofs;
+}
+
+static opc_bool_t opcZipRawReadLocalFileEx(opcIO_t *io, opcFileRawBuffer *raw, 
+                                    xmlChar *name, opc_uint32_t name_size, opc_uint32_t *name_len,
+                                    opc_uint32_t *header_size,
+                                    opc_uint32_t *min_header_size,
+                                    opc_uint32_t *compressed_size,
+                                    opc_uint32_t *uncompressed_size,
+                                    opc_uint16_t *bit_flag,
+                                    opc_uint32_t *crc32,
+                                    opc_uint16_t *compression_method,
+                                    opc_ofs_t *stream_ofs,
+                                    opc_uint16_t *growth_hint) {
+    opc_bool_t ret=OPC_FALSE;
+    opc_uint32_t sig=opcZipRawPeekHeaderSignature(io, raw);
+    if (0x04034b50==sig) {
+        *stream_ofs=raw->state.buf_pos;
+        opc_uint32_t header_signature;
+        opc_uint16_t filename_length;
+        opc_uint16_t extra_length;
+        opc_uint16_t dummy;
+        if (4==opcZipRawReadU32(io, raw, &header_signature) && header_signature==sig) // version_needed
+        if (2==opcZipRawReadU16(io, raw, &dummy)) // version_needed
+        if (2==opcZipRawReadU16(io, raw, bit_flag))
+        if (2==opcZipRawReadU16(io, raw, compression_method))
+        if (2==opcZipRawReadU16(io, raw, NULL)) // last_mod_time
+        if (2==opcZipRawReadU16(io, raw, NULL)) // last_mod_date
+        if (4==opcZipRawReadU32(io, raw, crc32)) // 
+        if (4==opcZipRawReadU32(io, raw, compressed_size))
+        if (4==opcZipRawReadU32(io, raw, uncompressed_size))
+        if (2==opcZipRawReadU16(io, raw, &filename_length))
+        if (2==opcZipRawReadU16(io, raw, &extra_length))
+        if ((*name_len=opcZipRawReadString(io, raw, name, filename_length, name_size))<=filename_length) {
+            *header_size=4*4+7*2+filename_length+extra_length;
+            *min_header_size=4*4+7*2+filename_length;
+            if (extra_length>=8) {
+                *min_header_size+=8;  // reserve space for the Microsoft Open Packaging Growth Hint
+            }
+            while(OPC_ERROR_NONE==raw->state.err && extra_length>0) {
+                opc_uint16_t extra_id;
+                opc_uint16_t extra_size;
+                if (2==opcZipRawReadU16(io, raw, &extra_id) && 2==opcZipRawReadU16(io, raw, &extra_size)) {
+                    switch(extra_id) {
+                    case 0xa220: // Microsoft Open Packaging Growth Hint => ignore
+                        {
+                            opc_uint16_t sig;
+                            opc_uint16_t padVal;
+                            if (2==opcZipRawReadU16(io, raw, &sig) && 0xa028==sig
+                                && 2==opcZipRawReadU16(io, raw, &padVal) 
+                                && extra_size>=4 && extra_size-4==opcZipRawSkipBytes(io, raw, extra_size-4)) {
+                                *growth_hint=padVal;
+                                extra_length-=4+extra_size;
+                            } else {
+                                raw->state.err=OPC_ERROR_STREAM;
+                            }
+                        }
+                        break;
+                    default: // just ignore
+                        opc_logf("**ignoring extra data id=%02X size=%02X\n", extra_id, extra_size);
+                        // no break;
+                        if (extra_size==opcZipRawSkipBytes(io, raw, extra_size)) {
+                            extra_length-=4+extra_size;
+                        } else {
+                            raw->state.err=OPC_ERROR_STREAM;
+                        }
+                        break;
+                    }
+                }
+                
+            }
+            ret=(OPC_ERROR_NONE==raw->state.err && 0==extra_length);
+        }
+    }
+    return ret;
+}
+
+static opc_error_t opcZipRawSkipFileData(opcIO_t *io, opcFileRawBuffer *raw, opc_uint32_t compressed_size) {
+    if (compressed_size!=opcZipRawSkipBytes(io, raw, compressed_size) && OPC_ERROR_NONE==raw->state.err) {
+        raw->state.err=OPC_ERROR_STREAM;
+    }
+    return raw->state.err;
+}
+
+static opc_error_t opcZipRawReadDataDescriptor(opcIO_t *io, opcFileRawBuffer *raw, opc_uint16_t bit_flag, opc_uint32_t *compressed_size, opc_uint32_t *uncompressed_size, opc_uint32_t *crc32, opc_uint32_t *trailing_bytes) {
+    OPC_ASSERT(0==*trailing_bytes);
+    if (0x8==(bit_flag & 0x8) && OPC_ERROR_NONE==raw->state.err) {
+        // streaming mode
+        OPC_ASSERT(0==*compressed_size);
+        opc_uint32_t sig=opcZipRawPeekHeaderSignature(io, raw);
+        if (0x08074b50==sig) {
+            opc_uint32_t header_signature;
+            OPC_ENSURE(4==opcZipRawReadU32(io, raw, &header_signature) && header_signature==sig);
+            *trailing_bytes+=4;
+        }
+        if (OPC_ERROR_NONE==raw->state.err) {
+            if ((4==opcZipRawReadU32(io, raw, crc32))
+            && (4==opcZipRawReadU32(io, raw, compressed_size))
+            && (4==opcZipRawReadU32(io, raw, uncompressed_size))) {
+                OPC_ASSERT(OPC_ERROR_NONE==raw->state.err);
+                *trailing_bytes+=3*4;
+            } else if (OPC_ERROR_NONE==raw->state.err) {
+                raw->state.err=OPC_ERROR_STREAM;
+            }
+        }
+    }
+    return raw->state.err;
+}
+
+static opc_error_t opcZipInitInflateState(opcFileRawState *rawState,
+                                   opc_uint32_t compressed_size,
+                                   opc_uint32_t uncompressed_size,
+                                   opc_uint16_t compression_method, 
+                                   opcZipInflateState *state) {
+    memset(state, 0, sizeof(*state));
+    state->stream.zalloc = Z_NULL;
+    state->stream.zfree = Z_NULL;
+    state->stream.opaque = Z_NULL;
+    state->stream.next_in = Z_NULL;
+    state->stream.avail_in = 0;
+    state->compressed_size=compressed_size;
+    state->compression_method=compression_method;
+    state->inflate_state = Z_STREAM_ERROR;
+    if (OPC_ERROR_NONE!=rawState->err) {
+        return rawState->err;
+    } else if (0==state->compression_method) { // STORE
+        return rawState->err;
+    } else if (8==state->compression_method) { // DEFLATE
+        if (Z_OK!=(state->inflate_state=inflateInit2(&state->stream, -MAX_WBITS))) {
+            rawState->err=OPC_ERROR_DEFLATE;
+        }
+        return rawState->err;
+    } else {
+        rawState->err=OPC_ERROR_UNSUPPORTED_COMPRESSION;
+        return rawState->err;
+    }
+}
+
+static opc_error_t opcZipCleanupInflateState(opcFileRawState *rawState, 
+                                      opc_uint32_t compressed_size,
+                                      opc_uint32_t uncompressed_size,
+                                      opcZipInflateState *state) {
+    if (OPC_ERROR_NONE==rawState->err) {
+        if (0==state->compression_method) { // STORE
+            if (state->stream.total_in!=compressed_size) {
+                rawState->err=OPC_ERROR_DEFLATE;
+            }
+        } else if (8==state->compression_method) { // DEFLATE
+            if (Z_OK!=(state->inflate_state=inflateEnd(&state->stream))) {
+                rawState->err=OPC_ERROR_DEFLATE;
+            } else if (state->stream.total_in!=compressed_size || state->stream.total_out!=uncompressed_size) {
+                rawState->err=OPC_ERROR_DEFLATE;
+            }
+        } else {
+            rawState->err=OPC_ERROR_UNSUPPORTED_COMPRESSION;
+        }
+    }
+    return rawState->err;
+}
+
+static opc_uint32_t opcZipRawReadFileData(opcIO_t *io, opcFileRawBuffer *rawBuffer, opcZipInflateState *state, opc_uint8_t *buffer, opc_uint32_t buf_len) {
+    if (8==state->compression_method) {
+        return opcZipRawInflateBuffer(io, rawBuffer, state, buffer, buf_len);
+    } else if (0==state->compression_method) {
+        opc_uint32_t const max_stream=state->compressed_size-state->stream.total_in;
+        opc_uint32_t const max_in=buf_len<max_stream?buf_len:max_stream;
+        int ret=opcZipRawReadBuffer(io, rawBuffer, buffer, max_in);
+        state->stream.total_in+=ret;
+        return ret;
+    } else {
+        return OPC_ERROR_UNSUPPORTED_COMPRESSION;
+    }
+}
+
+struct OPC_ZIPLOADER_IO_HELPER_STRUCT {
+    opcIO_t *io;
+    opcZipInflateState inflateState;
+    opcFileRawBuffer rawBuffer;
+    opcZipSegmentInfo_t info;
+};
+
+static int opcZipLoaderOpen(void *iocontext) {
+    struct OPC_ZIPLOADER_IO_HELPER_STRUCT *helper=(struct OPC_ZIPLOADER_IO_HELPER_STRUCT *)iocontext;
+    opc_error_t err=opcZipInitInflateState(&helper->rawBuffer.state, helper->info.compressed_size, helper->info.uncompressed_size, helper->info.compression_method, &helper->inflateState);
+    return (OPC_ERROR_NONE==err?0:-1);
+}
+
+static int opcZipLoaderRead(void *iocontext, char *buffer, int len) {
+    struct OPC_ZIPLOADER_IO_HELPER_STRUCT *helper=(struct OPC_ZIPLOADER_IO_HELPER_STRUCT *)iocontext;
+    opc_uint32_t ret=opcZipRawReadFileData(helper->io, &helper->rawBuffer, &helper->inflateState, (opc_uint8_t*)buffer, len);
+    return (OPC_ERROR_NONE==helper->rawBuffer.state.err?(int)ret:-1);
+}
+
+static int opcZipLoaderClose(void *iocontext) {
+    struct OPC_ZIPLOADER_IO_HELPER_STRUCT *helper=(struct OPC_ZIPLOADER_IO_HELPER_STRUCT *)iocontext;
+    opc_error_t err=opcZipRawReadDataDescriptor(helper->io, &helper->rawBuffer, helper->info.bit_flag, &helper->info.compressed_size, &helper->info.uncompressed_size, &helper->info.data_crc, &helper->info.trailing_bytes);
+    if (OPC_ERROR_NONE==err) {
+        err=opcZipCleanupInflateState(&helper->rawBuffer.state, helper->info.compressed_size, helper->info.uncompressed_size, &helper->inflateState);
+    }
+    return (OPC_ERROR_NONE==err?0:-1);
+}
+
+static int opcZipLoaderSkip(void *iocontext) {
+    struct OPC_ZIPLOADER_IO_HELPER_STRUCT *helper=(struct OPC_ZIPLOADER_IO_HELPER_STRUCT *)iocontext;
+    opc_error_t err=OPC_ERROR_NONE;
+    if (0x8==(helper->info.bit_flag & 0x8)) {
+        // streaming mode
+        if (8==helper->info.compression_method) {
+            if (0==opcZipLoaderOpen(iocontext)) {
+                char buf[OPC_DEFLATE_BUFFER_SIZE];
+                int ret=0;
+                while ((ret=opcZipLoaderRead(iocontext, buf, sizeof(buf)))>0);
+                if (OPC_ERROR_NONE==err && ret!=0) {
+                    err=OPC_ERROR_STREAM;
+                }
+                if (opcZipLoaderClose(iocontext)!=0 && OPC_ERROR_NONE==err) {
+                    err=OPC_ERROR_STREAM;
+                }
+            } else {
+                err=OPC_ERROR_STREAM;
+            }
+        } else {
+            OPC_ASSERT(0==helper->info.compression_method);
+            opc_uint8_t buf[3*sizeof(opc_uint32_t)];
+            if (sizeof(buf)==opcZipRawReadBuffer(helper->io, &helper->rawBuffer, buf, sizeof(buf))) {
+                opc_uint32_t stream_len=0;
+                opc_uint32_t crc=0;
+                do {
+                    opc_uint32_t v[3];
+                    opc_uint32_t k=0;
+                    for(opc_uint32_t j=0;j<3;j++) {
+                        v[j]=0;
+                        for(opc_uint32_t i=0;i<sizeof(opc_uint32_t);i++) {
+                            v[j]|=(opc_uint32_t)buf[(stream_len+(j*sizeof(v[0]))+i)%sizeof(buf)]<<(i<<3);
+                        }
+                    }
+                    opc_uint32_t skip_len=0;
+                    if (0x08074b50==v[0]) {
+                        // useless data descriptor signature, recalc v0..v3
+                        for(opc_uint32_t i=0;i<2;i++) v[i]=v[i+1];
+                        v[2]=opcZipRawPeekHeaderSignature(helper->io, &helper->rawBuffer);
+                        skip_len=sizeof(opc_uint32_t);
+                    }
+                    if (crc==v[0] && stream_len==v[1] && stream_len==v[2]) {
+                        if (OPC_ERROR_NONE==err && skip_len>0) {
+                            err=opcZipRawSkipFileData(helper->io, &helper->rawBuffer, skip_len);
+                        }
+                        // found valid data descriptor, assume this is the end of the local content
+                        if (OPC_ERROR_NONE==err) {
+                            helper->info.data_crc=v[0];
+                            helper->info.compressed_size=v[1];
+                            helper->info.uncompressed_size=v[2];
+                            helper->info.trailing_bytes=sizeof(buf)+skip_len;
+                        }
+                        break;
+                    } else {
+                        // check next byte
+                        crc=crc32(crc, &buf[stream_len%sizeof(buf)], sizeof(buf[0]));
+                        if (sizeof(buf[0])==opcZipRawReadBuffer(helper->io, &helper->rawBuffer, &buf[stream_len%sizeof(buf)], sizeof(buf[0]))) {
+                            stream_len++;
+                        } else {
+                            err=OPC_ERROR_STREAM;
+                            break;
+                        }
+                    }
+                } while(OPC_ERROR_NONE==helper->rawBuffer.state.err);
+            } else {
+                err=OPC_ERROR_STREAM; // not enough bytes for the trailing data descriptor => error
+            }
+        }
+    } else {
+        err=opcZipRawSkipFileData(helper->io, &helper->rawBuffer, helper->info.compressed_size);
+    }
+    return (OPC_ERROR_NONE==err?0:-1);
+}
+
+
+opc_error_t opcZipLoader(opcIO_t *io, void *userctx, opcZipLoaderSegmentCallback_t *segmentCallback) {
+    struct OPC_ZIPLOADER_IO_HELPER_STRUCT helper;
+    opc_bzero_mem(&helper, sizeof(helper));
+    helper.io=io;
+    OPC_ENSURE(OPC_ERROR_NONE==opcZipInitRawBuffer(io, &helper.rawBuffer));
+    while(OPC_ERROR_NONE==helper.rawBuffer.state.err &&
+        opcZipRawReadLocalFileEx(io, &helper.rawBuffer, helper.info.name, sizeof(helper.info.name), &helper.info.name_len,
+        &helper.info.header_size, &helper.info.min_header_size, &helper.info.compressed_size, &helper.info.uncompressed_size, &helper.info.bit_flag, &helper.info.data_crc, &helper.info.compression_method, &helper.info.stream_ofs, &helper.info.growth_hint)) {
+        OPC_ASSERT(helper.info.min_header_size<=helper.info.header_size);
+        helper.info.trailing_bytes=0;
+        OPC_ASSERT(NULL!=segmentCallback);
+        OPC_ENSURE(OPC_ERROR_NONE==opcHelperSplitFilename(helper.info.name, helper.info.name_len, &helper.info.segment_number, &helper.info.last_segment, &helper.info.rels_segment));
+        opc_error_t ret=segmentCallback(&helper, userctx, &helper.info, opcZipLoaderOpen, opcZipLoaderRead, opcZipLoaderClose, opcZipLoaderSkip);
+        OPC_ASSERT(OPC_ERROR_NONE==ret);
+        if (OPC_ERROR_NONE==helper.rawBuffer.state.err && OPC_ERROR_NONE!=ret) {
+            helper.rawBuffer.state.err=ret; // indicate an error
+        }
+    }
+    //@TODO verify directoy etc..
+#if 0
+                opcZipSegment segment;
+                xmlChar *name=NULL;
+                opc_uint32_t segment_number;
+                opc_bool_t last_segment;
+                while(opcZipRawReadCentralDirectory(zip, &rawBuffer, &segment, &name, &segment_number, &last_segment, NULL)) {
+                    OPC_ENSURE(OPC_ERROR_NONE==opcZipCleanupSegment(&segment));
+                    xmlFree(name);
+                }
+                opc_uint16_t central_dir_entries=0;
+                OPC_ENSURE(opcZipRawReadEndOfCentralDirectory(zip, &rawBuffer, &central_dir_entries));
+                for(opc_uint32_t i=0;i<container.part_items;i++) {
+                    opcZipSegmentInputStream *stream=opcZipCreateSegmentInputStream(zip, &container.part_array[i].segment);
+                    opc_uint8_t buf[OPC_DEFLATE_BUFFER_SIZE];
+                    opc_uint32_t len=0;
+                    opc_uint32_t crc=0;
+                    while((len=opcZipReadSegmentInputStream(zip, stream, buf, sizeof(buf)))>0) {
+                        crc=crc32(crc, buf, len);
+                    }
+                    OPC_ASSERT(crc==container.part_array[i].segment.crc32);
+                    printf("%s [%08X]\n", container.part_array[i].name, crc);
+                    OPC_ENSURE(OPC_ERROR_NONE==opcZipCloseSegmentInputStream(zip, &container.part_array[i].segment, stream));
+                }
+                for(opc_uint32_t i=0;i<container.part_items;i++) {
+                    OPC_ENSURE(OPC_ERROR_NONE==opcZipCleanupSegment(&container.part_array[i].segment));
+                    xmlFree(container.part_array[i].name);
+                }
+#endif
+
+    return helper.rawBuffer.state.err;
+}
+
+opcZipInputStream *opcZipOpenInputStream(opcZip *zip, opc_uint32_t segment_id) {
+    OPC_ASSERT(segment_id>=0 && segment_id<zip->segment_items);
+    opcZipInputStream *stream=(opcZipInputStream *)xmlMalloc(sizeof(opcZipInputStream));
+    if (NULL!=stream) {        
+        opc_bzero_mem(stream, sizeof(*stream));
+        stream->segment_id=segment_id;
+        opcZipSegment *segment=&zip->segment_array[segment_id];
+        stream->rawBuffer.state.buf_pos=segment->stream_ofs+segment->padding+segment->header_size;
+        if (OPC_ERROR_NONE!=opcZipInitInflateState(&stream->rawBuffer.state, 
+                                                   segment->compressed_size, 
+                                                   segment->uncompressed_size, 
+                                                   segment->compression_method, 
+                                                   &stream->inflateState)) {
+            // error
+            xmlFree(stream); stream=NULL;
+        }
+    }
+    return stream;
+}
+
+opc_error_t opcZipCloseInputStream(opcZip *zip, opcZipInputStream *stream) {
+    OPC_ASSERT(NULL!=zip && NULL!=stream);
+    OPC_ASSERT(stream->segment_id>=0 && stream->segment_id<zip->segment_items);
+    opcZipSegment *segment=&zip->segment_array[stream->segment_id];
+    opc_error_t err=opcZipCleanupInflateState(&stream->rawBuffer.state, 
+                                              segment->compressed_size, 
+                                              segment->uncompressed_size, 
+                                              &stream->inflateState);
+    xmlFree(stream); stream=NULL;
+    return err;
+}
+
+opc_uint32_t opcZipReadInputStream(opcZip *zip, opcZipInputStream *stream, opc_uint8_t *buf, opc_uint32_t buf_len) {
+    OPC_ASSERT(NULL!=zip && NULL!=stream);
+    OPC_ENSURE(stream->rawBuffer.state.buf_pos+stream->rawBuffer.buf_len-stream->rawBuffer.buf_ofs==_opcZipFileSeek(zip->io, stream->rawBuffer.state.buf_pos+stream->rawBuffer.buf_len-stream->rawBuffer.buf_ofs, opcFileSeekSet));
+    OPC_ASSERT(zip->io->state.buf_pos==stream->rawBuffer.state.buf_pos+stream->rawBuffer.buf_len-stream->rawBuffer.buf_ofs);
+
+//    OPC_ENSURE(stream->rawBuffer.state.buf_pos==_opcZipFileSeek(zip->io, stream->rawBuffer.state.buf_pos, opcFileSeekSet));
+    opc_uint32_t ret=opcZipRawReadFileData(zip->io, &stream->rawBuffer, &stream->inflateState, buf, buf_len);
+    return ret;
+}
+
+static opc_uint32_t opcZipAppendSegmentEx(opcZip *zip, 
+                                   opc_ofs_t stream_ofs,
+                                   opc_ofs_t segment_size,
+                                   opc_uint16_t padding,
+                                   opc_uint32_t header_size,
+                                   opc_uint16_t bit_flag,
+                                   opc_uint32_t crc32,
+                                   opc_uint16_t compression_method,
+                                   opc_ofs_t compressed_size,
+                                   opc_ofs_t uncompressed_size,
+                                   opc_uint32_t growth_hint,
+                                   const xmlChar *partName,
+                                   opc_bool_t relsSegment) {
+    opc_uint32_t segment_id=-1;
+    opcZipSegment *segment=ensureSegment(zip);
+    if (NULL!=segment) {
+        segment_id=zip->segment_items++;
+        opc_bzero_mem(segment, sizeof(*segment));
+        segment->stream_ofs=stream_ofs;
+        segment->padding=padding;
+        segment->header_size=header_size;
+        segment->segment_size=segment_size;
+        segment->bit_flag=bit_flag;
+        segment->crc32=crc32;
+        segment->compression_method=compression_method;
+        segment->compressed_size=compressed_size;
+        segment->uncompressed_size=uncompressed_size;
+        segment->growth_hint=growth_hint;
+        segment->partName=partName;
+        segment->rels_segment=(relsSegment?1:0);
+        segment->next_segment_id=-1;
+    }
+    return segment_id;
+}
+
+opc_uint32_t opcZipLoadSegment(opcZip *zip, const xmlChar *partName, opc_bool_t rels_segment, opcZipSegmentInfo_t *info) {
+    opc_uint32_t ret=opcZipAppendSegmentEx(zip, 
+                                           info->stream_ofs,
+                                           info->header_size+info->compressed_size+info->trailing_bytes,
+                                           info->header_size-info->min_header_size,
+                                           info->min_header_size, 
+                                           info->bit_flag,
+                                           info->data_crc,
+                                           info->compression_method,
+                                           info->compressed_size,
+                                           info->uncompressed_size,
+                                           info->growth_hint,
+                                           partName, 
+                                           rels_segment);
+    return ret;
+}
+
+opc_uint32_t opcZipCreateSegment(opcZip *zip, 
+                                 const xmlChar *partName, 
+                                 opc_bool_t relsSegment, 
+                                 opc_uint32_t segment_size, 
+                                 opc_uint32_t growth_hint,
+                                 opc_uint16_t compression_method,
+                                 opc_uint16_t bit_flag) {
+    OPC_ASSERT(0==compression_method || 8==compression_method); // either STORE or DEFLATE
+    OPC_ASSERT(8!=compression_method || (0<<1==bit_flag || 1<<1==bit_flag || 2<<1==bit_flag || 3<<1==bit_flag)); // WHEN DELFATE set bit_flag to NORMAL, MAXIMUM, FAST or SUPERFAST compression
+    opc_uint32_t segment_id=-1;
+    //@TODO find free segment
+    if (-1==segment_id) {
+        opc_ofs_t stream_ofs=(zip->segment_items>0?zip->segment_array[zip->segment_items-1].stream_ofs+zip->segment_array[zip->segment_items-1].segment_size:0);
+        opc_uint32_t _growth_hint=(growth_hint>0?growth_hint:OPC_DEFAULT_GROWTH_HINT);
+        opc_ofs_t _segment_size=(segment_size>0?segment_size:_growth_hint);
+        char name8[OPC_MAX_PATH];
+        opc_uint16_t name8_len=opcHelperAssembleSegmentName(name8, sizeof(name8), partName, 0, -1, relsSegment, NULL);
+        opc_uint32_t header_size=opcZipCalculateHeaderSize(name8, name8_len, OPC_TRUE, NULL);
+        if (OPC_ERROR_NONE==_opcZipFileGrow(zip->io, stream_ofs+_segment_size)) {
+            segment_id=opcZipAppendSegmentEx(zip, stream_ofs, _segment_size, 0, header_size, bit_flag, 0, compression_method, 0, 0, _growth_hint, partName, relsSegment);
+        }
+    }
+    return segment_id;
+}
+
+opc_error_t opcZipGC(opcZip *zip) {
+    for(opc_uint32_t i=1;i<zip->segment_items;i++) { 
+        OPC_ASSERT(zip->segment_array[i-1].stream_ofs+zip->segment_array[i-1].segment_size==zip->segment_array[i].stream_ofs);
+        if (!zip->segment_array[i-1].deleted_segment && !zip->segment_array[i].deleted_segment) {
+            opcZipSegment *segment=&zip->segment_array[i];
+            char name8[OPC_MAX_PATH];
+            opc_uint16_t name8_len=opcHelperAssembleSegmentName(name8, sizeof(name8), segment->partName,  0, -1, segment->rels_segment, NULL);
+            name8[name8_len]=0;
+            opc_uint32_t header_size=opcZipCalculateHeaderSize(name8, name8_len, OPC_TRUE, NULL);
+            if (header_size>segment->header_size) {
+                header_size=opcZipCalculateHeaderSize(name8, name8_len, OPC_FALSE, NULL);
+            }
+            OPC_ASSERT(header_size<=segment->header_size);
+            opc_uint32_t const free_space=segment->padding+(segment->header_size-header_size);
+            zip->segment_array[i-1].segment_size+=free_space;
+            OPC_ASSERT(segment->padding<=segment->segment_size);
+            segment->stream_ofs+=free_space;
+            segment->segment_size-=segment->padding;
+            segment->padding=0;
+            segment->header_size=header_size;
+        } 
+        OPC_ASSERT(zip->segment_array[i-1].stream_ofs+zip->segment_array[i-1].segment_size==zip->segment_array[i].stream_ofs);
+    }
+    return OPC_ERROR_NONE;
+}
+
+static void opcZipSegmentCalcReal(opcZip *zip, opc_uint32_t segment_id, opc_ofs_t *real_padding, opc_ofs_t *real_ofs) {
+    OPC_ASSERT(segment_id>=0 && segment_id<zip->segment_items);
+    *real_padding=zip->segment_array[segment_id].padding;
+    opc_uint32_t i=segment_id; 
+    for(;i>0 && zip->segment_array[i-1].deleted_segment;i--) {
+        *real_padding+=zip->segment_array[i-1].segment_size;
+    }
+    *real_ofs=zip->segment_array[i].stream_ofs;
+    if (i>0) {
+        OPC_ASSERT(!zip->segment_array[i-1].deleted_segment);
+        opc_ofs_t trailing_space=zip->segment_array[i].stream_ofs
+                                -zip->segment_array[i-1].stream_ofs
+                                -zip->segment_array[i-1].padding
+                                -zip->segment_array[i-1].header_size
+                                -zip->segment_array[i-1].compressed_size;
+        *real_ofs-=trailing_space;
+        *real_padding+=trailing_space;
+    }
+}
+
+static opc_bool_t opcZipValidate(opcZip *zip, opc_ofs_t *append_ofs) {
+    opc_bool_t valid=OPC_TRUE;
+    for(opc_uint32_t i=0;i<zip->segment_items;i++) { if (!zip->segment_array[i].deleted_segment) {
+        opc_ofs_t real_padding=0;
+        opc_ofs_t real_ofs=0;
+        opcZipSegmentCalcReal(zip, i, &real_padding, &real_ofs);
+        char name8[OPC_MAX_PATH];
+        opc_uint16_t name8_len=opcHelperAssembleSegmentName(name8, sizeof(name8), zip->segment_array[i].partName,  0, -1, zip->segment_array[i].rels_segment, NULL);
+        name8[name8_len]=0;
+        opc_uint32_t header_size=opcZipCalculateHeaderSize(name8, name8_len, OPC_TRUE, NULL);
+        valid=valid && (real_padding==0 || header_size<=zip->segment_array[i].header_size); // check padding>0 needs extra!
+        valid=valid&&(real_padding<65000); //@TODO get real value for max padding!
+        if (NULL!=append_ofs) *append_ofs=real_ofs+real_padding+zip->segment_array[i].compressed_size+zip->segment_array[i].header_size;
+    } }
+    return valid;
+}
+
+static void opcZipTrim(opcZip *zip, opc_ofs_t *append_ofs) {
+    opc_ofs_t ofs=0;
+    for(opc_uint32_t i=0;i<zip->segment_items;i++) { 
+        if (!zip->segment_array[i].deleted_segment) {
+            opc_ofs_t real_padding=0;
+            opc_ofs_t real_ofs=0;
+            opcZipSegmentCalcReal(zip, i, &real_padding, &real_ofs);
+            OPC_ASSERT(ofs<=real_ofs);
+            if (real_padding>0 || ofs<real_ofs) {
+                opc_ofs_t src_ofs=real_ofs+real_padding+zip->segment_array[i].header_size;
+                opc_ofs_t dest_ofs=ofs+zip->segment_array[i].header_size;
+                opc_ofs_t len=zip->segment_array[i].compressed_size;
+                OPC_ASSERT(dest_ofs<src_ofs);
+                if (dest_ofs<src_ofs) {
+                    OPC_ENSURE(OPC_ERROR_NONE==_opcZipFileMove(zip->io, dest_ofs, src_ofs, len));
+                }
+            }
+            zip->segment_array[i].stream_ofs=ofs;
+            zip->segment_array[i].padding=0;
+            zip->segment_array[i].segment_size=zip->segment_array[i].header_size+zip->segment_array[i].compressed_size;
+            for(opc_uint32_t j=i;j>0 && zip->segment_array[j-1].deleted_segment;j--) {
+                zip->segment_array[j-1].stream_ofs=ofs;
+                zip->segment_array[j-1].segment_size=0; // make it a "ZOMBI" segment
+                zip->segment_array[j-1].header_size=0; 
+                zip->segment_array[j-1].padding=0;
+            }
+            ofs+=zip->segment_array[i].segment_size;            
+        }
+    }
+    for(opc_uint32_t j=zip->segment_items;j>0 && zip->segment_array[j-1].deleted_segment;j--) {
+        zip->segment_array[j-1].stream_ofs=ofs;
+        zip->segment_array[j-1].segment_size=0; // make it a "ZOMBI" segment
+        zip->segment_array[j-1].header_size=0; 
+        zip->segment_array[j-1].padding=0;
+    }
+
+    for(opc_uint32_t i=1;i<zip->segment_items;i++) {
+        OPC_ASSERT(zip->segment_array[i-1].stream_ofs+zip->segment_array[i-1].segment_size==zip->segment_array[i].stream_ofs);
+    }
+    if (NULL!=append_ofs) *append_ofs=ofs;
+}
+
+static void opcZipUpdateLocalFileHeader(opcZip *zip) {
+    for(opc_uint32_t i=0;i<zip->segment_items;i++) { if (!zip->segment_array[i].deleted_segment) {
+        opc_ofs_t real_padding=0;
+        opc_ofs_t real_ofs=0;
+        opcZipSegmentCalcReal(zip, i, &real_padding, &real_ofs);
+        OPC_ENSURE(_opcZipFileSeek(zip->io, real_ofs, opcFileSeekSet)==real_ofs);
+        char name8[OPC_MAX_PATH];
+        opc_uint16_t name8_len=opcHelperAssembleSegmentName(name8, sizeof(name8), zip->segment_array[i].partName, 0, -1, zip->segment_array[i].rels_segment, NULL);
+//        opc_uint32_t header_size=opcZipCalculateHeaderSize(name8, name8_len, OPC_TRUE, NULL);
+        OPC_ASSERT(zip->segment_array[i].stream_ofs+zip->segment_array[i].padding==real_ofs+real_padding);
+        OPC_ENSURE(opcZipRawWriteSegmentHeaderEx(zip->io, &zip->io->state, 
+                                                 name8, name8_len, 
+                                                 zip->segment_array[i].bit_flag,
+                                                 zip->segment_array[i].crc32,
+                                                 zip->segment_array[i].compression_method,
+                                                 zip->segment_array[i].compressed_size,
+                                                 zip->segment_array[i].uncompressed_size,
+                                                 zip->segment_array[i].header_size+real_padding,
+                                                 zip->segment_array[i].growth_hint)==zip->segment_array[i].header_size+real_padding);
+        OPC_ASSERT(zip->segment_array[i].stream_ofs+zip->segment_array[i].padding+zip->segment_array[i].header_size==zip->io->state.buf_pos);
+    } }
+}
+
+static void opcZipAppendDirectory(opcZip *zip, opc_ofs_t append_ofs) {
+    OPC_ENSURE(_opcZipFileSeek(zip->io, append_ofs, opcFileSeekSet)==append_ofs);
+    opc_uint32_t real_segments=0;
+    for(opc_uint32_t i=0;i<zip->segment_items;i++) { if (!zip->segment_array[i].deleted_segment) {
+        opc_ofs_t real_padding=0;
+        opc_ofs_t real_ofs=0;
+        opcZipSegmentCalcReal(zip, i, &real_padding, &real_ofs);
+        char name8[OPC_MAX_PATH];
+        opc_uint16_t name8_len=opcHelperAssembleSegmentName(name8, sizeof(name8), zip->segment_array[i].partName, 0, -1, zip->segment_array[i].rels_segment, NULL);
+        OPC_ENSURE(OPC_ERROR_NONE==opcZipRawWriteCentralDirectoryEx(zip->io, &zip->io->state,
+                                                                    name8, name8_len, 
+                                                                    zip->segment_array[i].bit_flag,
+                                                                    zip->segment_array[i].crc32,
+                                                                    zip->segment_array[i].compression_method,
+                                                                    zip->segment_array[i].compressed_size,
+                                                                    zip->segment_array[i].uncompressed_size,
+                                                                    zip->segment_array[i].header_size+real_padding,
+                                                                    zip->segment_array[i].growth_hint,
+                                                                    real_ofs));
+        real_segments++;
+    } }
+    OPC_ENSURE(OPC_ERROR_NONE==opcZipRawWriteEndOfCentralDirectoryEx(zip->io, &zip->io->state, append_ofs, real_segments));
+    OPC_ENSURE(OPC_ERROR_NONE==_opcZipFileTrim(zip->io, zip->io->state.buf_pos));
+}
+
+opc_error_t opcZipCommit(opcZip *zip, opc_bool_t trim) {
+    opc_ofs_t append_ofs=0;
+    if (!opcZipValidate(zip, &append_ofs) || trim) {
+        opcZipTrim(zip, &append_ofs);
+        OPC_ASSERT(opcZipValidate(zip, NULL));
+    }
+    opcZipUpdateLocalFileHeader(zip);
+    opcZipAppendDirectory(zip, append_ofs);
+    OPC_ENSURE(OPC_ERROR_NONE==_opcZipFileFlush(zip->io));
+    return zip->io->state.err;
+}
+
+opcZipOutputStream *opcZipOpenOutputStream(opcZip *zip, opc_uint32_t *segment_id) {
+    OPC_ASSERT(NULL!=zip && NULL!=segment_id && -1!=*segment_id);
+    OPC_ASSERT(*segment_id>=0 && *segment_id<zip->segment_items);
+    opcZipSegment *segment=&zip->segment_array[*segment_id];
+    OPC_ASSERT(segment->header_size+segment->padding<=segment->segment_size);
+    opc_ofs_t free_size=segment->segment_size-segment->header_size-segment->padding;
+    opc_uint32_t buf_size=(free_size>OPC_DEFLATE_BUFFER_SIZE?OPC_DEFLATE_BUFFER_SIZE:free_size);
+    opcZipOutputStream *out=(opcZipOutputStream *)xmlMalloc(sizeof(opcZipOutputStream)+OPC_DEFLATE_BUFFER_SIZE);
+    if (NULL!=out) {
+        opc_bzero_mem(out, sizeof(*out));
+        out->buf=(opc_uint8_t*)((&out->buf)+1); // buffer starts right after me...
+        out->buf_size=buf_size;
+        out->segment_id=*segment_id;
+        *segment_id=-1; // take ownership
+        segment->compressed_size=0;
+        segment->uncompressed_size=0;
+        segment->crc32=0;
+        out->compression_method=segment->compression_method;
+        OPC_ASSERT(0==out->compression_method || 8==out->compression_method);
+        if (8==out->compression_method) { // delfate
+            out->stream.zalloc = Z_NULL;
+            out->stream.zfree = Z_NULL;
+            out->stream.opaque = Z_NULL;
+            int level=Z_DEFAULT_COMPRESSION;
+            switch ((segment->bit_flag>>1) & 0x3) {
+            default: 
+            case 0: level=Z_DEFAULT_COMPRESSION; 
+                break;
+            case 1: level=Z_BEST_COMPRESSION; 
+                break;
+            case 2: level=Z_BEST_SPEED; 
+                break;
+            case 3: level=Z_BEST_SPEED; 
+                break;
+            }
+            if (Z_OK!=(out->inflate_state=deflateInit2(&out->stream, level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY))) {
+                xmlFree(out); out=NULL;
+            }
+        }
+    }
+    return out;
+}
+
+opcZipOutputStream *opcZipCreateOutputStream(opcZip *zip, 
+                                             opc_uint32_t *segment_id, 
+                                             const xmlChar *partName, 
+                                             opc_bool_t relsSegment, 
+                                             opc_uint32_t segment_size, 
+                                             opc_uint32_t growth_hint,
+                                             opc_uint16_t compression_method,
+                                             opc_uint16_t bit_flag) {
+    opcZipOutputStream *ret=NULL;
+    OPC_ASSERT(NULL!=segment_id);
+    if (NULL!=segment_id) {
+        if (-1==*segment_id) {
+            *segment_id=opcZipCreateSegment(zip, partName, relsSegment, segment_size, growth_hint, compression_method, bit_flag);
+        } else {
+            OPC_ASSERT(*segment_id>=0 && *segment_id<zip->segment_items);
+            opcZipSegment *segment=&zip->segment_array[*segment_id];
+            segment->bit_flag=bit_flag;
+            segment->compression_method=compression_method;
+        }
+        ret=opcZipOpenOutputStream(zip, segment_id);
+    }
+    return ret;
+}
+
+static opc_uint32_t opcZipOutputStreamFill(opcZip *zip, opcZipOutputStream *stream, const opc_uint8_t *data, opc_uint32_t data_len) {
+    OPC_ASSERT(NULL!=stream && NULL!=stream->buf && NULL!=data && stream->buf_ofs+stream->buf_len<=stream->buf_size);
+    opc_uint32_t const free=stream->buf_size-stream->buf_ofs-stream->buf_len;
+    opc_uint32_t const len=(free<data_len?free:data_len);
+    opc_uint32_t ret=0;
+    OPC_ASSERT(len<=data_len && len<=stream->buf_size-(stream->buf_ofs+stream->buf_len));
+    if (len>0) {
+        if (0==stream->compression_method) { // STORE
+            stream->stream.total_in+=len;
+            stream->stream.total_out+=len;
+            stream->crc32=crc32(stream->crc32, data, len);
+            memcpy(stream->buf+stream->buf_ofs, data, len);
+            stream->buf_len+=len;
+            ret=len;
+        } else if (8==stream->compression_method) { // DEFLATE
+            stream->stream.avail_in=data_len;
+            stream->stream.next_in=(Bytef*)data;
+            stream->stream.avail_out=free;
+            stream->stream.next_out=stream->buf+stream->buf_ofs;
+            if (Z_OK==(stream->inflate_state=deflate(&stream->stream, Z_NO_FLUSH))) {
+                opc_uint32_t const bytes_in=data_len-stream->stream.avail_in;
+                opc_uint32_t const bytes_out=free-stream->stream.avail_out;
+                stream->crc32=crc32(stream->crc32, data, bytes_in);
+                ret=bytes_in;
+                stream->buf_len+=bytes_out;
+            } else {                
+                zip->io->state.err=OPC_ERROR_DEFLATE;
+            }
+        } else {
+            zip->io->state.err=OPC_ERROR_UNSUPPORTED_COMPRESSION;
+        }
+    }
+    return ret;
+}
+
+
+static opc_bool_t opcZipOutputStreamFinishCompression(opcZip *zip, opcZipOutputStream *stream) {
+    opc_bool_t ret=OPC_FALSE;
+    if (OPC_ERROR_NONE==zip->io->state.err) {
+        if (0==stream->compression_method) { // STORE
+            OPC_ASSERT(Z_OK==stream->inflate_state);
+            stream->inflate_state=Z_STREAM_END;
+            ret=(Z_STREAM_END==stream->inflate_state);
+        } else if (8==stream->compression_method) { // DEFLATE
+            opc_uint32_t const free=stream->buf_size-stream->buf_ofs-stream->buf_len;
+            OPC_ASSERT(free>0); // hmmm --- no space? make sure you correcly growed the segment...
+            stream->stream.avail_in=0;
+            stream->stream.next_in=0;
+            stream->stream.avail_out=free;
+            stream->stream.next_out=stream->buf+stream->buf_ofs;
+            if (Z_OK==(stream->inflate_state=deflate(&stream->stream, Z_FINISH)) || Z_STREAM_END==stream->inflate_state) {
+                opc_uint32_t const bytes_out=free-stream->stream.avail_out;
+                stream->buf_len+=bytes_out;
+                ret=(Z_STREAM_END==stream->inflate_state);
+            } else {
+                zip->io->state.err=OPC_ERROR_DEFLATE;
+            }
+        } else {
+            zip->io->state.err=OPC_ERROR_UNSUPPORTED_COMPRESSION;
+        }
+    }
+    return ret;
+}
+
+static void opcZipMarkSegmentDeleted(opcZip *zip, opc_uint32_t segment_id, opcZipSegmentReleaseCallback* releaseCallback) {
+    OPC_ASSERT(segment_id>=0 && segment_id<zip->segment_items);
+    opcZipSegment *segment=&zip->segment_array[segment_id];
+    if (NULL!=releaseCallback) releaseCallback(zip, segment_id);
+    segment->deleted_segment=1;
+    segment->partName=NULL; // should have been released in "releaseCallback" above
+    segment->next_segment_id=zip->first_free_segment_id;
+    zip->first_free_segment_id=segment_id;
+}
+
+static void opcZipOutputStreamFlushAndGrow(opcZip *zip, opcZipOutputStream *stream) {
+    opc_error_t err=OPC_ERROR_NONE;
+    if (stream->buf_len>0 && OPC_ERROR_NONE==zip->io->state.err) {
+        OPC_ASSERT(stream->segment_id>=0 && stream->segment_id<zip->segment_items);
+        opcZipSegment *segment=&zip->segment_array[stream->segment_id];
+        opc_ofs_t ofs=segment->padding+segment->header_size+segment->compressed_size;
+        OPC_ASSERT(ofs<=segment->segment_size);
+        opc_ofs_t free_space=segment->segment_size-ofs;
+        if (stream->buf_len>free_space && stream->segment_id+1==zip->segment_items) {
+            // not enoght space and last segment => simply grow it...
+            segment->growth_hint=(segment->growth_hint<=0?OPC_DEFAULT_GROWTH_HINT:segment->growth_hint);
+            OPC_ASSERT(segment->growth_hint>0);
+            while(segment->segment_size-ofs<stream->buf_len) segment->segment_size+=segment->growth_hint;
+            free_space=segment->segment_size-ofs;
+            OPC_ASSERT(stream->buf_len<=free_space);
+            OPC_ENSURE(OPC_ERROR_NONE==_opcZipFileGrow(zip->io, segment->stream_ofs+segment->segment_size));
+        }
+        if (stream->buf_len>free_space) {
+            // can't grow it, so move to a new segment!
+            opc_ofs_t size_needed=segment->segment_size+stream->buf_len+segment->header_size;
+            opc_uint32_t new_segment_id=opcZipCreateSegment(zip, segment->partName, segment->rels_segment, size_needed, segment->growth_hint, segment->compression_method, segment->bit_flag);
+            segment=&zip->segment_array[stream->segment_id]; // recalc segment, since create can realloc base address
+            if (OPC_ERROR_NONE==err && -1!=new_segment_id) {
+                OPC_ASSERT(new_segment_id>=0 && new_segment_id<zip->segment_items);
+                opcZipSegment *new_segment=&zip->segment_array[new_segment_id];
+                opc_ofs_t const free_size=new_segment->segment_size-new_segment->header_size-new_segment->padding;
+                OPC_ASSERT(segment->compressed_size<free_size);
+                err=_opcZipFileMove(zip->io,
+                                    new_segment->stream_ofs+new_segment->padding+new_segment->header_size, // dest
+                                    segment->stream_ofs+segment->padding+segment->header_size,  // src
+                                    segment->compressed_size);
+                new_segment->compressed_size=segment->compressed_size;
+                segment->partName=NULL; // ownership transfered to new_segment
+                opcZipMarkSegmentDeleted(zip, stream->segment_id, NULL /* no release needed, since partName is copied to new segment */);
+                OPC_ASSERT(1==segment->deleted_segment);
+                segment=new_segment;
+                stream->segment_id=new_segment_id;
+                opc_uint32_t buf_size=(free_size>OPC_DEFLATE_BUFFER_SIZE?OPC_DEFLATE_BUFFER_SIZE:free_size);
+                OPC_ASSERT(stream->buf_size<=buf_size);
+                stream->buf_size=buf_size;
+                ofs=segment->padding+segment->header_size+segment->compressed_size;
+                free_space=segment->segment_size-ofs;
+                OPC_ASSERT(stream->buf_len<=free_space);
+            }
+        }
+        if (stream->buf_len<=free_space) {
+            // enought free space in the current segment
+            OPC_ENSURE(_opcZipFileSeek(zip->io, segment->stream_ofs+ofs, opcFileSeekSet)==segment->stream_ofs+ofs);
+            OPC_ENSURE(_opcZipFileWrite(zip->io, stream->buf+stream->buf_ofs, stream->buf_len)==stream->buf_len);
+            segment->compressed_size+=stream->buf_len;
+            stream->buf_ofs=0;
+            stream->buf_len=0;
+        } else {
+            OPC_ASSERT(0); // should not happend! => can't get enought space!
+            err=OPC_ERROR_STREAM; 
+        }
+        if (OPC_ERROR_NONE!=err && OPC_ERROR_NONE==zip->io->state.err) {
+            zip->io->state.err=err;
+        }
+    }    
+}
+
+static void opcZipOutputStreamFinishSegment(opcZip *zip, opcZipOutputStream *stream) {
+    opc_bool_t done=OPC_FALSE;
+    while(!done && OPC_ERROR_NONE==zip->io->state.err) {
+        done=opcZipOutputStreamFinishCompression(zip, stream);
+        opcZipOutputStreamFlushAndGrow(zip, stream);
+    }
+}
+
+
+opc_error_t opcZipCloseOutputStream(opcZip *zip, opcZipOutputStream *stream, opc_uint32_t *segment_id) {
+    OPC_ASSERT(NULL!=zip && NULL!=segment_id && -1==*segment_id);
+    opcZipOutputStreamFinishSegment(zip, stream);
+    OPC_ASSERT(stream->segment_id>=0 && stream->segment_id<zip->segment_items);
+    opcZipSegment *segment=&zip->segment_array[stream->segment_id];
+    *segment_id=stream->segment_id;
+    OPC_ASSERT(segment->compressed_size==stream->stream.total_out);
+    segment->uncompressed_size=stream->stream.total_in;
+    segment->crc32=stream->crc32;
+    deflateEnd(&stream->stream);
+    xmlFree(stream); stream=NULL;
+    return zip->io->state.err;
+}
+
+opc_uint32_t opcZipWriteOutputStream(opcZip *zip, opcZipOutputStream *stream, const opc_uint8_t *buf, opc_uint32_t buf_len) {
+    opc_uint32_t out=0;
+    do {
+        out+=opcZipOutputStreamFill(zip, stream, buf+out, buf_len-out);
+        OPC_ASSERT(out<=buf_len);
+        opcZipOutputStreamFlushAndGrow(zip, stream);
+    } while (out<buf_len);
+    return out;
+}
+
+opc_uint32_t opcZipGetFirstSegmentId(opcZip *zip) {
+    opc_uint32_t i=0;
+    while(i<zip->segment_items && zip->segment_array[i].deleted_segment) i++;
+    return (i<zip->segment_items?i:-1);
+}
+
+opc_uint32_t opcZipGetNextSegmentId(opcZip *zip, opc_uint32_t segment_id) {
+    OPC_ASSERT(segment_id>=0 && segment_id<zip->segment_items);
+    if (segment_id>=0 && segment_id<zip->segment_items) {
+        opc_uint32_t i=segment_id+1;
+        while(i<zip->segment_items && zip->segment_array[i].deleted_segment) i++;
+        return (i<zip->segment_items?i:-1);
+    } else {
+        return -1;
+    }
+}
+
+opc_error_t opcZipGetSegmentInfo(opcZip *zip, opc_uint32_t segment_id, const xmlChar **name, opc_bool_t *rels_segment, opc_uint32_t *crc) {
+    OPC_ASSERT(segment_id>=0 && segment_id<zip->segment_items);
+    if (NULL!=name) {
+        *name=zip->segment_array[segment_id].partName;
+    }
+    if (NULL!=rels_segment) {
+        *rels_segment=zip->segment_array[segment_id].rels_segment;
+    }
+    if (NULL!=crc) {
+        *crc=zip->segment_array[segment_id].crc32;
+    }
+    return OPC_ERROR_NONE;
+}
+
+
+opc_bool_t opcZipSegmentDelete(opcZip *zip, opc_uint32_t *first_segment, opc_uint32_t *last_segment, opcZipSegmentReleaseCallback* releaseCallback) {
+    OPC_ASSERT(NULL==last_segment || *first_segment==*last_segment); // not not implemented... needed for fragmented containers
+    OPC_ASSERT(*first_segment>=0 && *first_segment<zip->segment_items);
+    opc_bool_t ret=OPC_FALSE;
+    opc_uint32_t segment_id=*first_segment;
+    while(segment_id>=0 && segment_id<zip->segment_items) {
+        opc_uint32_t next_segment_id=zip->segment_array[segment_id].next_segment_id;
+        opcZipMarkSegmentDeleted(zip, segment_id, releaseCallback);
+        segment_id=next_segment_id;
+    }
+    if (NULL!=last_segment) {
+        OPC_ASSERT(*last_segment=segment_id);
+        *last_segment=-1;
+    }
+    *first_segment=-1;
+    return ret;
+}

+ 255 - 0
opc/zip.h

@@ -0,0 +1,255 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+/** @file opc/zip.h
+  The ZIP file backend of an OPC container.
+ */
+#include <opc/config.h>
+#include <opc/file.h>
+#include <opc/container.h>
+
+#ifndef OPC_ZIP_H
+#define OPC_ZIP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif    
+
+    /**
+     Default growth hint of an OPC stream.
+     */
+    #define OPC_DEFAULT_GROWTH_HINT 512
+
+    /**
+     Handle to a ZIP archive.
+     \see internal.h
+     */
+    typedef struct OPC_ZIP_STRUCT opcZip;
+
+    /**
+      Handle to a raw ZIP input stream.
+     \see internal.h
+      */
+    typedef struct OPC_ZIPINPUTSTREAM_STRUCT opcZipInputStream;
+
+    /**
+      Handle to a raw ZIP output stream.
+     \see internal.h
+      */
+    typedef struct OPC_ZIPOUTPUTSTREAM_STRUCT opcZipOutputStream;
+
+    /**
+     Holds all information of a ZIP segment.
+     */
+    typedef struct OPC_ZIP_SEGMENT_INFO_STRUCT {
+        xmlChar name[OPC_MAX_PATH]; 
+        opc_uint32_t name_len;
+        opc_uint32_t segment_number;
+        opc_bool_t   last_segment;
+        opc_bool_t   rels_segment;
+        opc_uint32_t header_size;
+        opc_uint32_t min_header_size;
+        opc_uint32_t trailing_bytes;
+        opc_uint32_t compressed_size;
+        opc_uint32_t uncompressed_size;
+        opc_uint16_t bit_flag;
+        opc_uint32_t data_crc;
+        opc_uint16_t compression_method;
+        opc_ofs_t    stream_ofs;
+        opc_uint16_t growth_hint;
+    } opcZipSegmentInfo_t;
+
+    /**
+      \see opcZipLoader
+      */
+    typedef int opcZipLoaderOpenCallback(void *iocontext);
+    /**
+      \see opcZipLoader
+      */
+    typedef int opcZipLoaderSkipCallback(void *iocontext);
+    /**
+      \see opcZipLoader
+      */
+    typedef int opcZipLoaderReadCallback(void *iocontext, char *buffer, int len);
+    /**
+      \see opcZipLoader
+      */
+    typedef int opcZipLoaderCloseCallback(void *iocontext);
+
+    /**
+      \see opcZipLoader
+      */
+    typedef opc_error_t (opcZipLoaderSegmentCallback_t)(void *iocontext, void *userctx, opcZipSegmentInfo_t *info, opcZipLoaderOpenCallback *open, opcZipLoaderReadCallback *read, opcZipLoaderCloseCallback *close, opcZipLoaderSkipCallback *skip);
+
+    /**
+      Walks every segment in a ZIP archive and calls the \c segmentCallback callback method.
+      The implementer \c segmentCallback method must then eiher use the passed \c open, \c read and \c close methods
+      to read the stream or the passed \c skip methods to skip the stream.
+      This method can be used to e.g. read ZIP file in stream mode.
+      */
+    opc_error_t opcZipLoader(opcIO_t *io, void *userctx, opcZipLoaderSegmentCallback_t *segmentCallback);
+
+    /**
+      \see opcZipClose
+     */
+    typedef opc_error_t (opcZipSegmentReleaseCallback)(opcZip *zip, opc_uint32_t segment_id);
+
+    /** 
+     Closes the ZIP archive \c zip and will call \c releaseCallback for every segment to give the implementer a chance
+     to free user resources.
+     */
+    void opcZipClose(opcZip *zip, opcZipSegmentReleaseCallback* releaseCallback);
+
+    /**
+      Creates an empty ZIP archive with the given \c io.
+      */
+    opcZip *opcZipCreate(opcIO_t *io);
+
+    /**
+      Commits all buffers and writes the ZIP archives local header directories.
+      if \c trim is true then padding bytes will be removed, i.e. the ZIP file size fill be minimalized.
+     */
+    opc_error_t opcZipCommit(opcZip *zip, opc_bool_t trim);
+
+    /**
+      Garbage collection on the passed \c zip archive. This will e.g. make deleted files available as free space.
+      */
+    opc_error_t opcZipGC(opcZip *zip);
+
+    /**
+      Load segment information into \c info.
+      If \c rels_segment is -1 then load the info for part with name \c partName.
+      Otherwise load the segment information for the ".rels." segment of \c partName.
+      \return Returns the segment_id.
+      */
+    opc_uint32_t opcZipLoadSegment(opcZip *zip, const xmlChar *partName, opc_bool_t rels_segment, opcZipSegmentInfo_t *info);
+
+    /**
+      Create a segment with the given parameters.
+      \return Returns the segment_id.
+      */
+    opc_uint32_t opcZipCreateSegment(opcZip *zip, 
+                                     const xmlChar *partName, 
+                                     opc_bool_t relsSegment, 
+                                     opc_uint32_t segment_size, 
+                                     opc_uint32_t growth_hint,
+                                     opc_uint16_t compression_method,
+                                     opc_uint16_t bit_flag);
+
+    /**
+      Creates an input stream for the segment with \c segment_id.
+      \see opcZipLoadSegment
+      \see opcZipCreateSegment
+      */
+    opcZipInputStream *opcZipOpenInputStream(opcZip *zip, opc_uint32_t segment_id);
+
+    /**
+     Free all resources of the input stream.
+     */
+    opc_error_t opcZipCloseInputStream(opcZip *zip, opcZipInputStream *stream);
+
+    /**
+     Read maximal \c buf_len bytes from the input stream into \buf. 
+     \return Returns the number of bytes read.
+     */
+    opc_uint32_t opcZipReadInputStream(opcZip *zip, opcZipInputStream *stream, opc_uint8_t *buf, opc_uint32_t buf_len);
+
+
+    /**
+      Creates an output stream for the segment with \c segment_id.
+      If \c *segment_id is -1 then a new segment will be created. 
+      Otherwise the segment with \c *segment_id will be overwritten.
+     */
+    opcZipOutputStream *opcZipCreateOutputStream(opcZip *zip, 
+                                             opc_uint32_t *segment_id, 
+                                             const xmlChar *partName, 
+                                             opc_bool_t relsSegment, 
+                                             opc_uint32_t segment_size, 
+                                             opc_uint32_t growth_hint,
+                                             opc_uint16_t compression_method,
+                                             opc_uint16_t bit_flag);
+
+    /**
+      Opens an existing ouput stream for reading.
+      The \c *segment_id will be set to -1 and reset on opcZipCloseOutputStream.
+      \see opcZipCloseOutputStream
+     */
+    opcZipOutputStream *opcZipOpenOutputStream(opcZip *zip, opc_uint32_t *segment_id);
+
+    /** 
+      Will close the stream and free all resources. Additionally the new segment id will be stored in \c *segment_id.
+      \see opcZipOpenOutputStream
+      */
+    opc_error_t opcZipCloseOutputStream(opcZip *zip, opcZipOutputStream *stream, opc_uint32_t *segment_id);
+
+    /**
+     Write \c buf_len bytes to \c buf. 
+     \return Returns the number of bytes written.
+     */
+    opc_uint32_t opcZipWriteOutputStream(opcZip *zip, opcZipOutputStream *stream, const opc_uint8_t *buf, opc_uint32_t buf_len);
+
+    /**
+     Returns the first segment id or -1.
+     Use the following code to iterarte through all segments.
+     \code 
+     for(opc_uint32_t segment_id=opcZipGetFirstSegmentId(zip);
+         -1!=segment_id;
+         segment_id=opcZipGetNextSegmentId(zip, segment_id) {
+        ...
+     }
+     \endcode
+     \see opcZipGetNextSegmentId
+     */
+    opc_uint32_t opcZipGetFirstSegmentId(opcZip *zip);
+
+    /**
+     Returns the next segment id or -1.
+     \see opcZipGetFirstSegmentId
+     */
+    opc_uint32_t opcZipGetNextSegmentId(opcZip *zip, opc_uint32_t segment_id);
+
+    /**
+     Returns info about the given segment id.
+     */
+    opc_error_t opcZipGetSegmentInfo(opcZip *zip, opc_uint32_t segment_id, const xmlChar **name, opc_bool_t *rels_segment, opc_uint32_t *crc);
+
+    /**
+     Marks a given segments as deleted.
+     \see opcZipGC
+     */
+    opc_bool_t opcZipSegmentDelete(opcZip *zip, opc_uint32_t *first_segment, opc_uint32_t *last_segment, opcZipSegmentReleaseCallback* releaseCallback);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif    
+        
+#endif /* OPC_ZIP_H */

+ 1 - 0
plib/..svnbridge/Makefile.xml

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 1 - 0
plib/..svnbridge/configure

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 44 - 0
plib/Makefile.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<project>
+  <library name="plib">
+    <header root="{prjconfig}/{platform}/plib/include">
+      <file path="plib/plib.h" install="yes"/>
+    </header>
+    <header root=".">
+    </header>
+    <source root="source">
+	<file path="plib.c"/>
+    </source>
+  </library>
+</project>

+ 167 - 0
plib/config/msvc/plib/include/plib/plib.h

@@ -0,0 +1,167 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+   may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+#ifndef _PLIB_PLIB_H_
+#define _PLIB_PLIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef HAVE_STDINT_H
+#undef HAVE_STDDEF_H
+#undef HAVE_STDIO_H
+#undef HAVE_STRING_H
+#undef HAVE_LIMITS_H
+#undef HAVE_STDLIB_H
+#undef HAVE_IO_H
+#undef HAVE_UNISTD_H
+#undef HAVE_SYS_TYPES_H
+#undef IS_CONFIGURED
+
+#if !defined(IS_CONFIGURED)
+#if defined(WIN32)
+#define HAVE_STRING_H
+#define HAVE_STDINT_H
+#define HAVE_LIMITS_H
+#define HAVE_STDDEF_H
+#define HAVE_STDIO_H
+#define HAVE_STDLIB_H
+#define HAVE_IO_H
+#define snprintf _snprintf
+#else
+#error "configure not executed and we are not on a win32 machine? please run configure or define WIN32 is you are on a WIN32 platform."
+#endif
+#endif
+
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+typedef size_t pofs_t; // maximum file offset for eg. read write ops
+#else
+#error "system types can not be determined"
+#endif
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#else
+#error "system io can not be determined"
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+
+typedef int8_t pint8_t;
+typedef uint8_t puint8_t;
+
+typedef int16_t pint16_t;
+typedef uint16_t puint16_t;
+
+typedef int32_t pint32_t;
+typedef uint32_t puint32_t;
+
+typedef int64_t pint64_t;
+typedef uint64_t puint64_t;
+
+typedef int pbool_t;
+
+typedef size_t psize_t;
+
+// INTN_MAX, INTN_MIN, UINTN_MAX
+#else
+#error "system types can not be determined"
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#define PUINT8_MAX UCHAR_MAX 
+#define PINT32_MAX INT_MAX 
+#define PINT32_MIN INT_MIN 
+#define PUINT32_MAX UINT_MAX 
+#define PUINT32_MIN 0 
+#define PUINT16_MAX	USHRT_MAX 
+#define PUINT16_MIN 0 
+#else
+#error "limits can not be determined"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+/**
+ Converts an ASCII string to a xmlChar string. This only works for ASCII strings.
+ */
+#ifndef _X
+#define _X(s) BAD_CAST(s) 
+#endif
+
+
+/**
+ Converts an xmlChar string to an ASCII string. This only works for ASCII charsets.
+ */
+#ifndef _X2C
+#define _X2C(s) ((char*)(s))
+#endif
+
+
+#define PASSERT(e) assert(e)
+#ifdef NDEBUG
+#define PENSURE(e) (void)(e)
+#else
+#define PENSURE(e) assert(e)
+#endif
+#define PTRUE (0==0)
+#define PFALSE (0==1)
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+
+#endif /* _PLIB_PLIB_H_ */

+ 4253 - 0
plib/configure

@@ -0,0 +1,4253 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.67.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="plib"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used" >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.67
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval "test \"\${$3+set}\"" = set; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.67.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5 ; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5 ; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5 ; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5 ; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5 ; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5 ; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5 ; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in stdint.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdint_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDINT_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in stddef.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default"
+if test "x$ac_cv_header_stddef_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDDEF_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in stdio.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdio_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDIO_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in string.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STRING_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in limits.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIMITS_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in io.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default"
+if test "x$ac_cv_header_io_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_IO_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in unistd.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_UNISTD_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/types.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_types_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_TYPES_H 1
+_ACEOF
+
+fi
+
+done
+
+$as_echo "#define IS_CONFIGURED 1" >>confdefs.h
+
+ac_config_headers="$ac_config_headers include/plib/plib.h:config/msvc/plib/include/plib/plib.h"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.67.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration headers:
+$config_headers
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.67,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "include/plib/plib.h") CONFIG_HEADERS="$CONFIG_HEADERS include/plib/plib.h:config/msvc/plib/include/plib/plib.h" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_t"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "    :H $CONFIG_HEADERS    "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5  ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+    } >"$tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+ ;;
+
+
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+

+ 45 - 0
plib/configure.ac

@@ -0,0 +1,45 @@
+# Copyright (c) 2010, Florian Reuter
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without 
+# modification, are permitted provided that the following conditions 
+# are met:
+# 
+# * Redistributions of source code must retain the above copyright 
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright 
+#   notice, this list of conditions and the following disclaimer in 
+#   the documentation and/or other materials provided with the 
+#   distribution.
+# * Neither the name of Florian Reuter nor the names of its contributors 
+#   may be used to endorse or promote products derived from this 
+#   software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+AC_INIT([plib])
+AC_CHECK_HEADERS([stdint.h])
+AC_CHECK_HEADERS([stddef.h])
+AC_CHECK_HEADERS([stdio.h])
+AC_CHECK_HEADERS([string.h])
+AC_CHECK_HEADERS([limits.h])
+AC_CHECK_HEADERS([stdlib.h])
+AC_CHECK_HEADERS([io.h])
+AC_CHECK_HEADERS([unistd.h])
+AC_CHECK_HEADERS([sys/types.h])
+AC_DEFINE(IS_CONFIGURED)
+AC_CONFIG_HEADERS([include/plib/plib.h:config/msvc/plib/include/plib/plib.h])
+AC_OUTPUT
+

+ 34 - 0
plib/source/plib.c

@@ -0,0 +1,34 @@
+/*
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ */
+
+#include <plib/plib.h>

+ 202 - 0
regression.py

@@ -0,0 +1,202 @@
+#!/usr/bin/python
+
+import filecmp
+import os
+import sys
+import shlex
+import subprocess
+import json
+import shutil
+import platform as python_platform
+
+def msg(msg):
+	print msg+"...",
+
+def result(msg):
+	print msg;
+
+def failure(msg):
+	type, value = sys.exc_info()[:2]
+	if None == msg:
+		msg=value
+#	raise
+#	print msg
+	sys.exit(msg)
+
+
+
+def init(mode, type):
+	global TARGET_MODE
+	global TARGET_TYPE
+	global TMP_DIR
+	global BUILD_DIR
+	global DOCS_DIR
+	TARGET_MODE=mode.lower()
+	TARGET_TYPE=type.lower()
+	if "nt"==os.name:
+		TMP_DIR="win32"+os.sep+mode
+	else:
+		try:
+			msg("Reading configuration...")
+			f=open("build"+os.sep+"configure.ctx", "r")
+			ctx=eval(f.read())
+			f.close()
+			result("OK")
+		except:
+			failure("Can not open \"configure.ctx\". Try running ./configure first!")
+		msg("Guessing platform...")
+		if 1==len(ctx["platforms"]):
+			platform=ctx["platforms"][0]
+			result(platform)
+			TMP_DIR=os.path.join("build", platform, TARGET_TYPE)
+		else:
+			failure("Error. Please configure with exactly one platform!")
+	BUILD_DIR=TMP_DIR
+	DOCS_DIR="test_docs"
+
+
+def tmp(filename):
+	return os.path.join(TMP_DIR, filename)
+
+def build(filename):
+	return os.path.join(BUILD_DIR, filename)
+
+def docs(filename):
+	return os.path.join(DOCS_DIR, filename)
+
+
+def rm(filename):
+	try:
+		msg("remove "+filename)
+		if os.path.exists(filename):
+			os.remove(filename)
+		result("OK")
+	except:
+		failure(None)
+
+def cp(src, dst):
+	try:
+		msg("copy "+src+" to "+dst)
+		shutil.copyfile(src, dst)
+		result("OK")
+	except:
+		failure(None)
+
+def ensureDir(dir):
+	try:
+		if not(os.path.exists(dir)):
+			msg("creating dir "+dir)
+			os.makedirs(dir)
+			result("OK")
+	except:
+		failure(None)
+
+
+def call(path, pre, args, outfile, post, attr):
+	try:
+		env={}
+		if TARGET_TYPE=="shared":
+			if python_platform.system().lower()=="darwin":			
+				env["DYLD_LIBRARY_PATH"]=os.path.abspath(BUILD_DIR)
+			elif python_platform.system().lower()=="linux":			
+				env["LD_LIBRARY_PATH"]=os.path.abspath(BUILD_DIR)
+		msg("executing "+path)
+		if os.path.exists(tmp("stderr.txt")):
+			os.remove(tmp("stderr.txt"))
+		if os.path.exists(outfile):
+			os.remove(outfile)
+		_args = [ path ]
+		_args.extend(args)
+		err = open(tmp("stderr.txt"), "w")
+		out = open(outfile, "w")
+		ret=subprocess.call(_args, stdout=out, stderr=err, env=env)
+		out.close()
+		err.close()
+		if "return" in attr and ret!=int(attr["return"]):
+			failure("ERROR: return code is "+str(ret)+" but "+str(attr["return"])+" is expected.")
+		result("OK")
+	except:
+		failure(None)
+	
+def normlinebreak(path):
+	try:
+		msg("normalize line breaks "+path+"...")		
+		newlines = []
+		changed  = False
+		for line in open(path, 'rb').readlines():
+			if line[-2:] == '\r\n':
+				line = line[:-2] + '\n'
+				changed = True
+			newlines.append(line)
+		if changed:
+			open(path, 'wb').writelines(newlines)
+			result("Changed")
+		else:
+			result("OK")
+	except:
+		failure(None)
+	
+
+def regr(regrpath, path, normalize):
+	if normalize:
+		normlinebreak(regrpath)
+		normlinebreak(path)	
+	msg("regression testing "+path+" against "+regrpath)
+	eq=filecmp.cmp(regrpath, path)
+	if (eq):
+		result("OK")
+	else:
+		failure("Regression test failed!")
+
+def compile(path):
+	try:
+		msg("compiling "+path)
+		if os.path.exists(tmp("stderr.txt")):
+			os.remove(tmp("stderr.txt"))
+		if os.path.exists(tmp("stdout.txt")):
+			os.remove(tmp("stdout.txt"))
+		err = open(tmp("stderr.txt"), "w")
+		out = open(tmp("stdout.txt"), "w")
+		exe=os.path.abspath(os.path.splitext(path)[0]+".exe")
+		obj=os.path.abspath(os.path.splitext(path)[0]+".obj")
+		if TARGET_MODE == "debug":
+			rtl="/MDd"
+		else:
+			rtl="/MD"
+		cl_args=["cl", 
+			os.path.abspath(path), 
+			"/Fo"+obj,
+			"/TP", "/c", rtl,
+			"/I..\\..\\config\\win32-msvc\\zlib-1.2.5",
+			"/I..\\..\\third_party\\zlib-1.2.5",
+			"/I..\\..\\config\\win32-msvc\\libxml2-2.7.7",
+			"/I..\\..\\third_party\\libxml2-2.7.7\\include\\libxml",
+			"/I..\\..\\third_party\\libxml2-2.7.7\\include",
+			"/I..\\..\\plib\\config\\msvc\\plib\\include",
+			"/I..\\..\\config",
+			"/I..\\..",
+			"/D", "WIN32",
+			"/D", "LIBXML_STATIC",
+			"/D","_UNICODE",
+			"/D", "UNICODE" ]
+		link_args=["link", "/OUT:"+os.path.abspath(exe),  os.path.abspath(os.path.splitext(path)[0]+".obj"),"/NOLOGO", "/MACHINE:X86",
+			"kernel32.lib", "user32.lib", "gdi32.lib", "winspool.lib", "comdlg32.lib", "advapi32.lib", "shell32.lib", "ole32.lib", "oleaut32.lib", "uuid.lib", "odbc32.lib", "odbccp32.lib", 
+			"mce.lib", "opc.lib", "plib.lib", "zlib.lib", "xml.lib" ]
+		cwd=os.getcwd()
+		os.chdir(tmp(""))
+		ret=subprocess.call(cl_args, stdout=out, stderr=err)
+		if ret==0:
+			ret=subprocess.call(link_args, stdout=out, stderr=err)
+		os.chdir(cwd)
+		out.close()
+		err.close()
+		if ret==0:
+			result("OK")
+		else:
+			out = open(tmp("stdout.txt"), "r")
+			out_str=out.read()
+			out.close()
+			failure("FAIL:\n"+out_str)
+		return exe
+	except:
+		failure(None)

+ 5 - 0
sample/..svnbridge/Makefile.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:ignore</Name><Value>build
+doc
+*.o
+third_party
+</Value></Property><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 1 - 0
sample/..svnbridge/opc_changes.c

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 1 - 0
sample/..svnbridge/opc_proc.c

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 1 - 0
sample/..svnbridge/opc_properties.c

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:executable</Name><Value>*</Value></Property></Properties></ItemProperties>

+ 127 - 0
sample/Makefile.xml

@@ -0,0 +1,127 @@
+<project>
+    <tool name="opc_helloworld" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_helloworld.c"/>
+        </source>
+    </tool>
+    <tool name="opc_zipread" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_zipread.c"/>
+        </source>
+    </tool>
+    <tool name="opc_zipextract" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_zipextract.c"/>
+        </source>
+    </tool>
+    <tool name="opc_zipwrite" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_zipwrite.c"/>
+        </source>
+    </tool>
+    <tool name="opc_dump" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_dump.c"/>
+        </source>
+    </tool>
+    <tool name="opc_trim" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_trim.c"/>
+        </source>
+    </tool>
+    <tool name="opc_mem" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_mem.c"/>
+        </source>
+    </tool>
+    <tool name="opc_extract" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_extract.c"/>
+        </source>
+    </tool>
+    <tool name="opc_xml" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_xml.c"/>
+        </source>
+    </tool>
+    <tool name="opc_xml2" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_xml2.c"/>
+        </source>
+    </tool>
+    <tool name="opc_part" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_part.c"/>
+        </source>
+    </tool>
+    <tool name="opc_relation" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_relation.c"/>
+        </source>
+    </tool>
+    <tool name="opc_type" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_type.c"/>
+        </source>
+    </tool>
+    <tool name="opc_image" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_image.c"/>
+        </source>
+    </tool>
+    <tool name="opc_text" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_text.c"/>
+        </source>
+    </tool>
+    <tool name="opc_generate" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_generate.c"/>
+        </source>
+    </tool>
+    <tool name="opc_album" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_album.c"/>
+        </source>
+    </tool>
+    <tool name="opc_properties" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_properties.c"/>
+        </source>
+    </tool>
+    <tool name="mcepp" dep="mce" mode="c99">
+        <source root=".">
+            <file path="mcepp.c"/>
+        </source>
+    </tool>
+    <tool name="mce_read" dep="opc mce" mode="c99">
+        <source root=".">
+            <file path="mce_read.c"/>
+        </source>
+    </tool>
+    <tool name="mce_write" dep="opc mce" mode="c99">
+        <source root=".">
+            <file path="mce_write.c"/>
+        </source>
+    </tool>
+    <tool name="mce_extract" dep="opc mce" mode="c99">
+        <source root=".">
+            <file path="mce_extract.c"/>
+        </source>
+    </tool>
+    <tool name="opc_changes" dep="opc" mode="c99">
+        <source root=".">
+            <file path="opc_changes.c"/>
+        </source>
+    </tool>
+    <tool name="mce_schema" dep="opc" mode="c99">
+        <source root=".">
+            <file path="mce_schema.c"/>
+        </source>
+    </tool>
+    <tool name="opc_proc" dep="opc" mode="c99">
+      <source root=".">
+        <file path="opc_proc.c"/>
+      </source>
+    </tool>
+</project>

+ 165 - 0
sample/mce_extract.c

@@ -0,0 +1,165 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Dump an XML part using the non-MCE opcXmlReader.
+
+    Ussage:
+    opc_xml FILENAME PARTNAME
+
+    Sample:
+    opc_xml OOXMLI1.docx "word/document.xml"
+*/
+
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#include <libxml/xmlwriter.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+
+static int  xmlOutputWrite(void * context, const char * buffer, int len) {
+    FILE *out=(FILE*)context;
+    return fwrite(buffer, sizeof(char), len, out);
+}
+
+static int xmlOutputClose(void * context) {
+    return 0;
+}
+
+static void dumpPartsAsJSON(opcContainer *c, int indent) {
+    printf("["); if (indent) printf("\n");
+    opcPart part=OPC_PART_INVALID;
+    opcPart next=OPC_PART_INVALID;
+    for(part=opcPartGetFirst(c);OPC_PART_INVALID!=part;part=next) {
+        next=opcPartGetNext(c, part);
+        if (indent) {
+            printf("  {\n    \"name\": \"%s\",\n    \"type\":\"%s\"\n  }%s\n", part, opcPartGetType(c, part), (OPC_PART_INVALID==next?"":","));
+        } else {
+            printf("{\"name\": \"%s\", \"type\":\"%s\"}%s", part, opcPartGetType(c, part), (OPC_PART_INVALID==next?"":","));
+        }
+    }
+    printf("]"); if (indent) printf("\n");
+}
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    int ret=-1;
+    time_t start_time=time(NULL);
+    FILE *file=NULL;
+    const xmlChar *containerPath8=NULL;
+    const xmlChar *partName8=NULL;
+    xmlTextWriter *writer=NULL;
+    int writer_indent=0;
+    opc_bool_t reader_mce=OPC_TRUE;
+    for(int i=1;i<argc;i++) {
+        if ((0==xmlStrcmp(_X("--understands"), _X(argv[i])) || 0==xmlStrcmp(_X("-u"), _X(argv[i]))) && i+1<argc) {
+	    i++; // skip namespace, registered later when parser was created.
+        } else if ((0==xmlStrcmp(_X("--out"), _X(argv[i])) || 0==xmlStrcmp(_X("--out"), _X(argv[i]))) && i+1<argc && NULL==file) {
+            const char *filename=argv[++i];
+            file=fopen(filename, "w");
+        } else if (0==xmlStrcmp(_X("--indent"), _X(argv[i]))) {
+            writer_indent=1;
+        } else if (0==xmlStrcmp(_X("--raw"), _X(argv[i]))) {
+            reader_mce=OPC_FALSE;
+        } else if (NULL==containerPath8) {
+            containerPath8=_X(argv[i]);
+        } else if (NULL==partName8) {
+            partName8=_X(argv[i]);
+        } else {
+            fprintf(stderr, "IGNORED: %s\n", argv[i]);
+        }
+    }
+    if (NULL!=file) {
+        xmlOutputBuffer *out=xmlOutputBufferCreateIO(xmlOutputWrite, xmlOutputClose, file, NULL);
+        if (NULL!=out) {
+            writer=xmlNewTextWriter(out);
+        }
+    } else {
+        xmlOutputBuffer *out=xmlOutputBufferCreateIO(xmlOutputWrite, xmlOutputClose, stdout, NULL);
+        if (NULL!=out) {
+            writer=xmlNewTextWriter(out);
+        }
+    }
+    if (NULL==containerPath8 || NULL==writer) {
+        printf("mce_extract FILENAME.\n\n");
+        printf("Sample: mce_extract test.docx word/document.xml\n");
+    } else if (OPC_ERROR_NONE==opcInitLibrary()) {
+        xmlTextWriterSetIndent(writer, writer_indent);
+        opcContainer *c=NULL;
+        if (NULL!=(c=opcContainerOpen(containerPath8, OPC_OPEN_READ_ONLY, NULL, NULL))) {
+            if (NULL==partName8) {
+                dumpPartsAsJSON(c, writer_indent);
+            } else {
+                opcPart part=OPC_PART_INVALID;
+                if ((part=opcPartFind(c, partName8, NULL, 0))!=OPC_PART_INVALID) {
+                    mceTextReader_t reader;
+                    if (OPC_ERROR_NONE==opcXmlReaderOpen(c, &reader, part, NULL, NULL, 0)) {
+                        mceTextReaderDisableMCE(&reader, !reader_mce);
+                        for(int i=1;i<argc;i++) {
+                            if ((0==xmlStrcmp(_X("--understands"), _X(argv[i])) || 0==xmlStrcmp(_X("-u"), _X(argv[i]))) && i+1<argc) {
+                                const xmlChar *ns=_X(argv[++i]);
+                                mceTextReaderUnderstandsNamespace(&reader, ns);
+                            }
+                        }
+
+                        if (-1==mceTextReaderDump(&reader, writer, PTRUE)) {
+                            ret=mceTextReaderGetError(&reader);
+                        } else {
+                            ret=0;
+                        }
+                        mceTextReaderCleanup(&reader);
+                    } else {
+                        fprintf(stderr, "ERROR: part \"%s\" could not be opened for XML reading.\n", argv[2]);
+                    }
+                } else {
+                    fprintf(stderr, "ERROR: part \"%s\" could not be opened in \"%s\".\n", argv[2], argv[1]);
+                }
+            }
+            opcContainerClose(c, OPC_CLOSE_NOW);
+        } else {
+            fprintf(stderr, "ERROR: file \"%s\" could not be opened.\n", argv[1]);
+        }
+        opcFreeLibrary();
+    } else {
+        fprintf(stderr, "ERROR: initialization of libopc failed.\n");    
+    }
+    if (NULL!=writer) xmlFreeTextWriter(writer);
+    if (NULL!=file) fclose(file);
+    time_t end_time=time(NULL);
+    fprintf(stderr, "time %.2lfsec\n", difftime(end_time, start_time));
+    return ret;
+}

+ 73 - 0
sample/mce_read.c

@@ -0,0 +1,73 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <mce/textreader.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    xmlInitParser();
+    const char *src=NULL;
+    const char *dst=NULL;
+    for(int i=1;i<argc;i++) {
+        if (0==strcmp("--understands", argv[i])) i++;
+        else if (NULL==src) src=argv[i];
+        else if (NULL==dst) dst=argv[i];
+        else printf("skipped argument %s\n", argv[i]);
+    }
+    if (NULL!=dst && NULL!=src) {
+        mceTextReader_t reader;
+        if (-1!=mceTextReaderInit(&reader, xmlNewTextReaderFilename(src))) {
+            for(int i=1;i<argc;i++) {
+                if (0==strcmp("--understands", argv[i])) {
+                    mceTextReaderUnderstandsNamespace(&reader, _X(argv[++i]));
+                }
+            }
+            xmlTextWriterPtr writer=xmlNewTextWriterFilename(dst, 0);
+            mceTextReaderDump(&reader, writer, PFALSE);
+            xmlFreeTextWriter(writer);
+            mceTextReaderCleanup(&reader);
+        } else {
+            printf("ERROR: file \"%s\" could not be opened.\n", argv[1]);
+        }
+    } else {
+        printf("mce_read [--understands NAMESPACE] SRC.XML TARGET.XML\n");
+    }
+    xmlCleanupParser();
+    return 0;
+}

+ 550 - 0
sample/mce_schema.c

@@ -0,0 +1,550 @@
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+static pbool_t specialChar(int ch) {
+    return ch<'0' || (ch>'9' && ch<'A') || (ch>'Z' && ch<'a' && '_'!=ch) || ch>'z';
+}
+
+xmlChar *readSourceLine(FILE *f) {
+    xmlChar *ret=NULL;
+    int len=0;
+    int ch=0;
+    while(EOF!=(ch=fgetc(f)) && '\n'!=ch) {
+        ret=(xmlChar *)xmlRealloc(ret, len+2); // +2 => reserve trailing "0" too
+        if (NULL!=ret) {
+            pbool_t ws=(ch==' ' || ch=='\t' || ch=='\r' || ch=='\n');
+            if (ws) {
+                pbool_t preceeding_ws=(len==0 && ws);
+                if (len>0 && !specialChar(ret[len-1])) {
+                    ret[len++]=' ';
+                }
+            } else {
+                if (len>0 && specialChar(ch) && ret[len-1]==' ') {
+                    len--;
+                }
+                ret[len++]=ch;
+            }
+            ret[len]=0;
+        }
+    }
+    if ('\n'==ch && 0==len) {
+        ret=(xmlChar *)xmlRealloc(ret, len+1);
+        if (NULL!=ret) {
+            ret[len]=0;
+        }
+    }
+    return ret;
+}
+
+typedef enum LINE_TOKEN_ID {
+    LINE_TOKEN_ID_DEF,
+    LINE_TOKEN_ID_REF,
+    LINE_TOKEN_ID_START_DOCUMENT,
+    LINE_TOKEN_ID_END_DOCUMENT,
+    LINE_TOKEN_ID_START_ELEMENT,
+    LINE_TOKEN_ID_END_ELEMENT,
+    LINE_TOKEN_ID_START_CHILDREN,
+    LINE_TOKEN_ID_END_CHILDREN,
+    LINE_TOKEN_ID_SKIP_CHILDREN,
+    LINE_TOKEN_ID_START_ATTRIBUTES,
+    LINE_TOKEN_ID_END_ATTRIBUTES,
+    LINE_TOKEN_ID_SKIP_ATTRIBUTES,
+    LINE_TOKEN_ID_START_CHOICE,
+    LINE_TOKEN_ID_END_CHOICE,
+    LINE_TOKEN_ID_MATCH_ELEMENT,
+    LINE_TOKEN_ID_MATCH_ATTRIBUTE,
+    LINE_TOKEN_ID_START_TEXT,
+    LINE_TOKEN_ID_END_TEXT,
+    LINE_TOKEN_ID_START_ATTRIBUTE,
+    LINE_TOKEN_ID_END_ATTRIBUTE,
+    LINE_TOKEN_ID_INVALID,
+    LINE_TOKEN_ID_EOF
+} LineTokenId_t;
+
+typedef struct LINE_TOKEN_DECLARATION {
+    LineTokenId_t id;
+    char name[50];
+} LineTokenDeclaration;
+
+static LineTokenDeclaration s_token[] = {
+    { LINE_TOKEN_ID_DEF, "mce_def"}, 
+    { LINE_TOKEN_ID_REF, "mce_ref"}, 
+    { LINE_TOKEN_ID_START_DOCUMENT, "mce_start_document" },
+    { LINE_TOKEN_ID_END_DOCUMENT, "mce_end_document" },
+    { LINE_TOKEN_ID_START_ELEMENT, "mce_start_element" },
+    { LINE_TOKEN_ID_END_ELEMENT, "mce_end_element" },
+    { LINE_TOKEN_ID_START_CHILDREN, "mce_start_children" },
+    { LINE_TOKEN_ID_END_CHILDREN, "mce_end_children" },
+    { LINE_TOKEN_ID_SKIP_CHILDREN, "mce_skip_children" },
+    { LINE_TOKEN_ID_START_ATTRIBUTES, "mce_start_attributes" },
+    { LINE_TOKEN_ID_END_ATTRIBUTES, "mce_end_attributes" },
+    { LINE_TOKEN_ID_SKIP_ATTRIBUTES, "mce_skip_children" },
+    { LINE_TOKEN_ID_START_CHOICE, "mce_start_choice" },
+    { LINE_TOKEN_ID_END_CHOICE, "mce_end_choice" },
+    { LINE_TOKEN_ID_MATCH_ELEMENT, "mce_match_element" },
+    { LINE_TOKEN_ID_MATCH_ATTRIBUTE, "mce_match_attribute" },
+    { LINE_TOKEN_ID_START_TEXT, "mce_start_text" },
+    { LINE_TOKEN_ID_END_TEXT, "mce_end_text" },
+    { LINE_TOKEN_ID_START_ATTRIBUTE, "mce_start_attribute" },
+    { LINE_TOKEN_ID_END_ATTRIBUTE, "mce_end_attribute" },
+    { LINE_TOKEN_ID_INVALID, "" },
+    { LINE_TOKEN_ID_EOF, "" }
+};
+
+typedef struct LINE_TOKEN_INSTANCE {
+    LineTokenId_t id;
+    char param[3][255];
+} LineTokenInstance;
+
+typedef struct SOURCE_QNAME {
+    xmlChar *p;
+    xmlChar *ns;
+} SourceQName;
+
+
+typedef struct SCHEMA_DECLARATION {
+    xmlChar *ns;
+    xmlChar *ln;
+    puint32_t def_id;
+} SchemaDeclaration;
+
+
+typedef struct SCHEMA_DEFINITION {
+    xmlChar *name; // if definition has a name
+    puint32_t max_occurs;
+    SchemaDeclaration *attr_array;
+    puint32_t attr_len;
+    SchemaDeclaration *decl_array;
+    puint32_t decl_len;
+} SchemaDefinition;
+
+typedef struct SOURCE_CONTEXT {
+    FILE *f;
+    SourceQName *binding_array;
+    puint32_t binding_len;
+    SchemaDefinition *def_array;
+    puint32_t def_len;
+    SchemaDeclaration *decl_array;
+    puint32_t decl_len;
+    pbool_t error_flag;
+} SourceContext;
+
+
+static void addBinding(SourceContext *sc, const xmlChar *p, const xmlChar *ns) {
+    puint32_t i=0; 
+    while(i<sc->binding_len && 0!=xmlStrcmp(sc->binding_array[i].p, p)) i++;
+    if (i==sc->binding_len) {
+        sc->binding_array=(SourceQName*)xmlRealloc(sc->binding_array, (sc->binding_len+1)*sizeof(SourceQName));
+        i=sc->binding_len++;
+        memset(sc->binding_array+i, 0, sizeof(sc->binding_array[i]));
+        sc->binding_array[i].p=xmlStrdup(p);
+    } else {
+        OPC_ASSERT(0==xmlStrcmp(sc->binding_array[i].p, p));
+    }
+    if (NULL!=sc->binding_array && i<sc->binding_len) {
+        if (NULL!=sc->binding_array[i].ns) xmlFree(sc->binding_array[i].ns);
+        sc->binding_array[i].ns=xmlStrdup(ns);
+    }
+}
+
+static xmlChar *getBinding(SourceContext *sc, const xmlChar *p) {
+    puint32_t i=0; 
+    while(i<sc->binding_len && 0!=xmlStrcmp(sc->binding_array[i].p, p)) i++;
+    if (i<sc->binding_len) {
+        return sc->binding_array[i].ns;
+    } else {
+        return NULL;
+    }
+}
+
+static puint32_t addDef(SourceContext *sc, xmlChar *def) {
+    sc->def_array=(SchemaDefinition*)xmlRealloc(sc->def_array, (sc->def_len+1)*sizeof(SchemaDefinition));
+    if (NULL!=sc->def_array) {
+        puint32_t i=sc->def_len++;
+        memset(&sc->def_array[i], 0, sizeof(sc->def_array[i]));
+        if (NULL!=def) {
+            sc->def_array[i].name=xmlStrdup(def);
+        }
+        return i;
+    } else {
+        return -1;
+    }
+}
+
+static puint32_t findDef(SourceContext *sc, xmlChar *def) {
+    for(puint32_t i=0;i<sc->def_len;i++) {
+        if (NULL!=sc->def_array[i].name && 0==xmlStrcmp(sc->def_array[i].name, def)) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+static void freeDecls(SchemaDeclaration **decl_array, puint32_t *decl_len);
+static void freeDef(SchemaDefinition *def) {
+    if (NULL!=def->name) xmlFree(def->name);
+    freeDecls(&def->decl_array, &def->decl_len);
+}
+
+
+static SchemaDeclaration* addDecl(SchemaDeclaration **decl_array, puint32_t *decl_len, const xmlChar *ns, const xmlChar *ln) {
+    *decl_array=(SchemaDeclaration *)xmlRealloc(*decl_array, (1+*decl_len)*sizeof(SchemaDeclaration));
+    if (NULL!=*decl_array) {
+        memset((*decl_array)+(*decl_len), 0, sizeof((*decl_array)[(*decl_len)]));
+        (*decl_array)[(*decl_len)].def_id=-1;
+        if (NULL!=ns) (*decl_array)[(*decl_len)].ns=xmlStrdup(ns);
+        if (NULL!=ln) (*decl_array)[(*decl_len)].ln=xmlStrdup(ln);
+        return (*decl_array)+(*decl_len)++;
+    } else {
+        return NULL;
+    }
+}
+
+static void freeDecls(SchemaDeclaration **decl_array, puint32_t *decl_len) {
+    if (NULL!=*decl_array) {
+        for(puint32_t j=0;j<*decl_len;j++) {
+            if (NULL!=(*decl_array)[j].ln) xmlFree((*decl_array)[j].ln);
+            if (NULL!=(*decl_array)[j].ns) xmlFree((*decl_array)[j].ns);
+        }
+        xmlFree(*decl_array);
+    }
+}
+
+static void readParam(SourceContext *sc, xmlChar *line, int *ofs, char *param, int param_max) {
+    int j=0;
+    while(line[*ofs]!=0 && line[*ofs]!=',') {
+        if (j+2<param_max) {
+            if ('('==line[*ofs]) {
+                j=0;
+            }
+            if ('\"'==line[*ofs] || !specialChar(line[*ofs])) {
+                param[j++]=line[*ofs];
+            }
+            param[j]=0;
+        }
+        (*ofs)++;
+    }
+    if (j>1 && '\"'==param[0] && '\"'==param[j-1]) {
+        for(int i=0;i<j-2;i++) {
+            param[i]=param[i+1];
+        }
+        param[j-2]=0;
+    } else if (NULL!=sc) {
+        xmlChar *v=getBinding(sc, _X(param));
+        if (NULL!=v && xmlStrlen(v)+1<param_max) {
+            strcpy(param, (const char *)v);
+        } else {
+            printf("ERROR: can not resolve %s\n", param);
+        }
+    }
+}
+
+static int findStringInLine(xmlChar *line, const xmlChar *str) {
+    int i=0;
+    int str_len=xmlStrlen(str);
+    while(0!=line[i] && 0!=xmlStrncmp(line+i, str, str_len)) {
+        i++;
+    }
+    if (0==xmlStrncmp(line+i, str, str_len)) {
+        return i;
+    } else {
+        return -1;
+    }
+}
+
+LineTokenId_t readLineToken(SourceContext *sc, LineTokenInstance* ti) {
+    static const char ns_decl[]="static const char ";
+    memset(ti, 0, sizeof(*ti));
+    ti->id=LINE_TOKEN_ID_INVALID;
+    while(!sc->error_flag) {
+        xmlChar *line=readSourceLine(sc->f);
+        if (NULL!=line) {
+            int ofs=-1;
+            int mce_def_ofs=-1;
+            if ('#'==line[0] && 'd'==line[1] && 'e'==line[2] && 'f'==line[3] && 'i'==line[4] && 'n'==line[5] && 'e'==line[6]) {
+                // filter out #define s
+            } else if (-1!=(mce_def_ofs=findStringInLine(line, _X("mce_def ")))) {
+                ti->id=LINE_TOKEN_ID_DEF;
+                int j=0;
+                ofs=mce_def_ofs+xmlStrlen(_X("mce_def "));
+                while(line[ofs]!=0 && !specialChar(line[ofs])) {
+                    if (j+2<sizeof(ti->param[0])) {
+                        ti->param[0][j++]=line[ofs];
+                        ti->param[0][j]=0;
+                    }
+                    ofs++;
+                }
+            } else if (-1!=(mce_def_ofs=findStringInLine(line, _X("mce_ref(")))) {
+                ti->id=LINE_TOKEN_ID_REF;
+                int j=0;
+                ofs=mce_def_ofs+xmlStrlen(_X("mce_ref("));
+                while(line[ofs]!=0 && !specialChar(line[ofs])) {
+                    if (j+2<sizeof(ti->param[0])) {
+                        ti->param[0][j++]=line[ofs];
+                        ti->param[0][j]=0;
+                    }
+                    ofs++;
+                }
+            } else {
+                if ('m'==line[0] && 'c'==line[1] && 'e'==line[2] && '_'==line[3]) {
+                    ofs=0;
+                } else if ('}'==line[0] && 'm'==line[1] && 'c'==line[2] && 'e'==line[3] && '_'==line[4]) {
+                    ofs=1;
+                }
+                if (ofs>=0) {
+                    int t=0; while (LINE_TOKEN_ID_INVALID!=s_token[t].id && 0!=xmlStrncmp(_X(s_token[t].name), line+ofs, xmlStrlen(_X(s_token[t].name)))) t++;
+                    if (LINE_TOKEN_ID_INVALID!=s_token[t].id) {
+                        ti->id=s_token[t].id;
+                        PASSERT(0==xmlStrncmp(_X(s_token[ti->id].name), line+ofs, xmlStrlen(_X(s_token[ti->id].name))));
+                        ofs+=xmlStrlen(_X(s_token[t].name));
+                        readParam(NULL, line, &ofs, ti->param[0], sizeof(ti->param[0]));
+                        if (line[ofs]==',') { ofs++; readParam(sc, line, &ofs, ti->param[1], sizeof(ti->param[1])); }
+                        if (line[ofs]==',') { ofs++; readParam(sc, line, &ofs, ti->param[2], sizeof(ti->param[2])); }
+                    } else {
+        //                printf("UNKOWN TOKEN: %s\n", line);
+                    }
+                } else if (0==xmlStrncmp(_X(ns_decl), line, xmlStrlen(_X(ns_decl)))) {
+                    char prefix[50];
+                    char ns[255];
+                    int ofs=xmlStrlen(_X(ns_decl));
+                    int j=0;
+                    while(0!=line[ofs] && '['!=line[ofs]) {
+                        if (j+2<sizeof(prefix)) {
+                            prefix[j++]=line[ofs];
+                            prefix[j]=0;
+                        }
+                        ofs++;
+                    }
+                    if (line[ofs]=='[') {
+                        while(0!=line[ofs] && '\"'!=line[ofs]) ofs++;
+                        if ('\"'==line[ofs]) {
+                            ofs++;
+                            int j=0;
+                            while(0!=line[ofs] && '\"'!=line[ofs]) {
+                                if (j+2<sizeof(ns)) {
+                                    ns[j++]=line[ofs];
+                                    ns[j]=0;
+                                }
+                                ofs++;
+                            }
+                            if ('\"'==line[ofs]) {
+                                addBinding(sc, _X(prefix), _X(ns));
+                            }
+                        }
+                    }
+                }
+            }
+            xmlFree(line);
+            if (LINE_TOKEN_ID_INVALID!=ti->id) {
+                return ti->id;
+            }
+        } else {
+            ti->id=LINE_TOKEN_ID_EOF;
+            return ti->id;
+        }
+    }
+    ti->id=LINE_TOKEN_ID_EOF; // error
+    return ti->id;
+}
+
+static void errorToken(SourceContext *sc, LineTokenInstance *ti) {
+    printf("ERROR %s(%s, %s, %s)\n", s_token[ti->id].name, ti->param[0], ti->param[1], ti->param[2]);
+    ti->id=LINE_TOKEN_ID_EOF;
+    sc->error_flag=PTRUE;
+}
+
+static pbool_t parseDeclarations(SourceContext *sc, LineTokenInstance *ti, puint32_t def_id);
+static pbool_t parseStartDeclaration(SourceContext *sc, LineTokenInstance *ti, SchemaDeclaration **decl_array, puint32_t *decl_len) {
+    if (LINE_TOKEN_ID_START_ELEMENT==ti->id || LINE_TOKEN_ID_START_ATTRIBUTE==ti->id || LINE_TOKEN_ID_START_TEXT==ti->id) {
+        LineTokenId_t const end_id=(LINE_TOKEN_ID_START_ELEMENT==ti->id
+                                   ?LINE_TOKEN_ID_END_ELEMENT:LINE_TOKEN_ID_START_ATTRIBUTE==ti->id?LINE_TOKEN_ID_END_ATTRIBUTE
+                                                                                                   :LINE_TOKEN_ID_START_TEXT==ti->id
+                                                                                                   ?LINE_TOKEN_ID_END_TEXT:ti->id);
+
+        SchemaDeclaration *decl=addDecl(decl_array, decl_len, _X(ti->param[1]), _X(ti->param[2]));
+        PASSERT(NULL!=decl && -1==decl->def_id);
+        readLineToken(sc, ti); // consume start token
+        if (LINE_TOKEN_ID_REF==ti->id) {
+            decl->def_id=findDef(sc, _X(ti->param[0]));
+            if (-1==decl->def_id) {
+                decl->def_id=addDef(sc, _X(ti->param[0]));
+            }
+        } else {
+            decl->def_id=addDef(sc, NULL);
+        }
+        PASSERT(NULL!=decl && -1!=decl->def_id);
+        if (decl->def_id>=0 && decl->def_id<sc->def_len) {
+            parseDeclarations(sc, ti, decl->def_id); // attributes
+            parseDeclarations(sc, ti, decl->def_id); // children
+            if (end_id==ti->id) {
+                sc->def_array[decl->def_id].max_occurs=PUINT32_MAX;
+                readLineToken(sc, ti); // consume end token
+                return PTRUE;
+            }
+        }
+    }
+    return PFALSE;
+}
+
+static pbool_t parseDeclarations(SourceContext *sc, LineTokenInstance *ti, puint32_t def_id) {
+    if (LINE_TOKEN_ID_START_CHILDREN==ti->id) {
+        readLineToken(sc, ti); // consume start token
+        while(parseStartDeclaration(sc, ti, &sc->def_array[def_id].decl_array, &sc->def_array[def_id].decl_len)) {
+        }
+        if (LINE_TOKEN_ID_END_CHILDREN==ti->id) {
+            readLineToken(sc, ti); // consume end token
+            return PTRUE;
+        } else {
+            return PFALSE;
+        }
+    } else if (LINE_TOKEN_ID_START_ATTRIBUTES==ti->id) {
+        readLineToken(sc, ti); // consume start token
+        while(parseStartDeclaration(sc, ti, &sc->def_array[def_id].attr_array, &sc->def_array[def_id].attr_len)) {
+        }
+        if (LINE_TOKEN_ID_END_ATTRIBUTES==ti->id) {
+            readLineToken(sc, ti); // consume end token
+            return PTRUE;
+        } else {
+            return PFALSE;
+        }
+    } else if (LINE_TOKEN_ID_SKIP_CHILDREN==ti->id) {
+        readLineToken(sc, ti); // consume token
+        return PTRUE;
+    } else if (LINE_TOKEN_ID_SKIP_ATTRIBUTES==ti->id) {
+        readLineToken(sc, ti); // consume token
+        return PTRUE;
+    } else if (LINE_TOKEN_ID_REF==ti->id) {
+        readLineToken(sc, ti); // consume token
+        return PTRUE;
+    } else {
+        return PFALSE;
+    }
+}
+
+
+static pbool_t parseStartDocument(SourceContext *sc, LineTokenInstance *ti) {
+    if (LINE_TOKEN_ID_START_DOCUMENT==ti->id) {
+        readLineToken(sc, ti); // consume start_document token
+        if (parseStartDeclaration(sc, ti, &sc->decl_array, &sc->decl_len)) {
+            return (LINE_TOKEN_ID_END_DOCUMENT==ti->id?LINE_TOKEN_ID_INVALID!=readLineToken(sc, ti):PFALSE); // consume end_document
+        }
+    } 
+    return PFALSE;
+}
+
+static pbool_t parseDefinition(SourceContext *sc, LineTokenInstance *ti) {
+    if (LINE_TOKEN_ID_DEF==ti->id) {
+        puint32_t def_id=findDef(sc, _X(ti->param[0]));
+        if (-1==def_id) {
+            def_id=addDef(sc, _X(ti->param[0]));
+        }
+        PASSERT(-1!=def_id);
+        readLineToken(sc, ti); // consume def token
+        if (def_id>=0 && def_id<sc->def_len) {
+            parseDeclarations(sc, ti, def_id); // attributes
+            parseDeclarations(sc, ti, def_id); // children
+            return PTRUE;
+        }
+    } 
+    return PFALSE;
+}
+
+static void dumpDecl(SourceContext *sc, FILE *out, int indent, SchemaDeclaration *decl);
+static void dumpDef(SourceContext *sc, FILE *out, int indent, puint32_t def_id) {
+    printf("%*sattrs:\n", indent, "");
+    for(puint32_t i=0;i<sc->def_array[def_id].attr_len;i++) {
+        dumpDecl(sc, out, indent, &sc->def_array[def_id].attr_array[i]);
+    }
+    printf("%*schildren:\n", indent, "");
+    for(puint32_t i=0;i<sc->def_array[def_id].decl_len;i++) {
+        dumpDecl(sc, out, indent, &sc->def_array[def_id].decl_array[i]);
+    }
+}
+
+
+static void dumpDecl(SourceContext *sc, FILE *out, int indent, SchemaDeclaration *decl) {
+    pbool_t const has_children=(decl->def_id>=0 && decl->def_id<sc->def_len && NULL==sc->def_array[decl->def_id].name && (sc->def_array[decl->def_id].attr_len>0 || sc->def_array[decl->def_id].decl_len>0));
+    fprintf(out, "%*s\"%s\" \"%s\" -> \"%s\" %s\n", indent, "", decl->ns, decl->ln, sc->def_array[decl->def_id].name, (has_children?" {":""));
+    if (has_children) {
+        dumpDef(sc, out, indent+2, decl->def_id);
+        fprintf(out, "%*s}\n", indent, "");
+    }
+}
+
+void dumpGrammar(SourceContext *sc, FILE *out) {
+    for(puint32_t i=0;i<sc->def_len;i++) {
+        if (NULL!=sc->def_array[i].name) {
+            fprintf(out, "def %s {\n", sc->def_array[i].name);
+            dumpDef(sc, out, 2, i);
+            fprintf(out, "}\n");
+        }
+    }
+    fprintf(out, "start {\n");
+    for(puint32_t i=0;i<sc->decl_len;i++) {
+        dumpDecl(sc, out, 2, &sc->decl_array[i]);
+    }
+    fprintf(out, "}\n");
+}
+
+void parseSourceCode(SourceContext *sc, xmlChar *filename) {
+    sc->f=fopen((const char*)filename, "r");
+    if (NULL!=sc->f) {
+        LineTokenInstance ti;
+        readLineToken(sc, &ti); // read first token
+        while(LINE_TOKEN_ID_EOF!=ti.id) {
+            if (parseStartDocument(sc, &ti)) {
+            } else if (parseDefinition(sc, &ti)) {
+            } else {
+                errorToken(sc, &ti);
+                readLineToken(sc, &ti); // consumer token, try to recover
+            }
+        }
+        fclose(sc->f);
+    }
+}
+
+void parseSchema(xmlChar *filename) {
+    mceTextReader_t reader;
+    if (0==mceTextReaderInit(&reader, xmlNewTextReaderFilename((const char*)filename))) {
+        mce_start_document(&reader) {
+
+        } mce_end_document(&reader);
+        mceTextReaderCleanup(&reader);
+    }
+}
+
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    opcInitLibrary();
+    SourceContext sc;
+    memset(&sc, 0, sizeof(sc));
+    addBinding(&sc, _X("NULL"), _X("*"));
+    for(int i=1;i<argc;i++) {
+        parseSourceCode(&sc, _X(argv[i]));
+    }
+    dumpGrammar(&sc, stdout);
+    if (NULL!=sc.binding_array) {
+        for(puint32_t i=0;i<sc.binding_len;i++) {
+            if (NULL!=sc.binding_array[i].p) xmlFree(sc.binding_array[i].p);
+            if (NULL!=sc.binding_array[i].ns) xmlFree(sc.binding_array[i].ns);
+        }
+        xmlFree(sc.binding_array);
+    }
+    freeDecls(&sc.decl_array, &sc.decl_len);
+    if (NULL!=sc.def_array) {
+        for(puint32_t i=0;i<sc.def_len;i++) {
+            freeDef(&sc.def_array[i]);
+        }
+        xmlFree(sc.def_array);
+    }
+    opcFreeLibrary();
+    return 0;
+}

+ 122 - 0
sample/mce_write.c

@@ -0,0 +1,122 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <opc/opc.h>
+#include <mce/textwriter.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+const char v1_ns[]="http://schemas.openxmlformats.org/Circles/v1";
+const char v2_ns[]="http://schemas.openxmlformats.org/Circles/v2";
+const char v3_ns[]="http://schemas.openxmlformats.org/Circles/v3";
+
+/*
+ Produces sample 10-3 from ISO-IEC-29500 Part 3:
+ 
+ <Circles xmlns="http://schemas.openxmlformats.org/Circles/v1" 
+          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+          xmlns:v2="http://schemas.openxmlformats.org/Circles/v2" 
+          mc:Ignorable="v2" 
+          mc:ProcessContent="v2:Blink" > 
+  <v2:Watermark Opacity="v0.1"> 
+   <Circle Center="0,0" Radius="20" Color="Blue" /> 
+   <Circle Center="25,0" Radius="20" Color="Black" /> 
+   <Circle Center="50,0" Radius="20" Color="Red" /> 
+  </v2:Watermark> 
+  <v2:Blink> 
+   <Circle Center="13,0" Radius="20" Color="Yellow" /> 
+   <Circle Center="38,0" Radius="20" Color="Green" /> 
+  </v2:Blink> 
+ </Circles> 
+ 
+ */
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    if (OPC_ERROR_NONE==opcInitLibrary()) {
+        if (2==argc) {
+            opcContainer *c=opcContainerOpen(_X(argv[1]), OPC_OPEN_WRITE_ONLY, NULL, NULL);
+            opcExtensionRegister(c, _X("xml"), _X("text/xml"));
+            opcPart part=opcPartCreate(c, _X("sample.xml"), NULL, 0);
+            mceTextWriter *w=mceTextWriterOpen(c, part, OPC_COMPRESSIONOPTION_FAST);
+            mceTextWriterStartDocument(w);
+            mceTextWriterRegisterNamespace(w, _X(v1_ns), NULL, MCE_DEFAULT);
+            mceTextWriterRegisterNamespace(w, _X(v2_ns), _X("v2"), MCE_IGNORABLE);
+            mceTextWriterProcessContent(w, _X(v2_ns), _X("Blink"));
+            mceTextWriterStartElement(w, _X(v1_ns), _X("Circles"));
+            mceTextWriterStartElement(w, _X(v2_ns), _X("Watermark"));
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Opacity"), "v0.1");    
+            mceTextWriterStartElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Center"), "0,0");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Radius"), "20");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Color"), "Blue");
+            mceTextWriterEndElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterStartElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Center"), "25,0");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Radius"), "20");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Color"), "Black");
+            mceTextWriterEndElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterStartElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Center"), "50,0");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Radius"), "20");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Color"), "Red");
+            mceTextWriterEndElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterEndElement(w, _X(v2_ns), _X("Watermark"));
+
+            mceTextWriterStartElement(w, _X(v2_ns), _X("Blink"));
+            mceTextWriterStartElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Center"), "13,0");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Radius"), "20");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Color"), "Yellow");
+            mceTextWriterEndElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterStartElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Center"), "38,0");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Radius"), "20");
+            mceTextWriterAttributeF(w, _X(v1_ns), _X("Color"), "Green");
+            mceTextWriterEndElement(w, _X(v1_ns), _X("Circle"));
+            mceTextWriterEndElement(w, _X(v2_ns), _X("Blink")); 
+                
+            mceTextWriterEndElement(w, _X(v1_ns), _X("Circles"));
+            mceTextWriterEndDocument(w);
+            mceTextWriterFree(w);
+            opcContainerClose(c, OPC_CLOSE_NOW);
+        } else {
+            printf("mce_write sample.zip\n");
+        }
+        opcFreeLibrary();
+    }
+    return 0;
+}

+ 103 - 0
sample/mcepp.c

@@ -0,0 +1,103 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <mce/textreader.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/xmlreader.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    int ret=-1;
+    time_t start_time=time(NULL);
+    FILE *file=NULL;
+    int writer_indent=0;
+    pbool_t reader_mce=PTRUE;
+    const char *fileName=NULL;
+    for(int i=1;i<argc;i++) {
+        if ((0==xmlStrcmp(_X("--understands"), _X(argv[i])) || 0==xmlStrcmp(_X("-u"), _X(argv[i]))) && i+1<argc) {
+            i++; // skip namespace, registered later when parser was created.
+        } else if ((0==xmlStrcmp(_X("--out"), _X(argv[i])) || 0==xmlStrcmp(_X("--out"), _X(argv[i]))) && i+1<argc && NULL==file) {
+            const char *filename=argv[++i];
+            file=fopen(filename, "w");
+        } else if (0==xmlStrcmp(_X("--indent"), _X(argv[i]))) {
+            writer_indent=1;
+        } else if (0==xmlStrcmp(_X("--raw"), _X(argv[i]))) {
+            reader_mce=PFALSE;
+        } else if (NULL==fileName) {
+            fileName=argv[i];
+        } else {
+            fprintf(stderr, "IGNORED: %s\n", argv[i]);
+        }
+    }
+    xmlTextWriter *writer=xmlNewTextWriterFile(file);
+    if (NULL==fileName || NULL==writer) {
+        printf("mcepp [--understands NAMESPACE] [--out FILENAME] [--indent] [--raw] [FILENAME | - ]\n\n");
+        printf("Sample: mcepp sample.xml\n");
+    } else {
+        xmlInitParser();
+        xmlTextWriterSetIndent(writer, writer_indent);
+        mceTextReader_t mceTextReader;
+        mceTextReaderInit(&mceTextReader, ('-'==fileName[0] && 0==fileName[1]?xmlReaderForFd(0, NULL, NULL, 0):xmlReaderForFile(fileName, NULL, 0)));
+        mceTextReaderDisableMCE(&mceTextReader, !reader_mce);
+        for(int i=1;i<argc;i++) {
+            if ((0==xmlStrcmp(_X("--understands"), _X(argv[i])) || 0==xmlStrcmp(_X("-u"), _X(argv[i]))) && i+1<argc) {
+                const xmlChar *ns=_X(argv[++i]);
+                mceTextReaderUnderstandsNamespace(&mceTextReader, ns);
+            }
+        }
+
+        if (-1==mceTextReaderDump(&mceTextReader, writer, PFALSE)) {
+            ret=mceTextReaderGetError(&mceTextReader);
+        } else {
+            ret=0;
+        }
+        mceTextReaderCleanup(&mceTextReader);
+        xmlCleanupParser();
+    }
+    if (NULL!=writer) xmlFreeTextWriter(writer);
+    if (NULL!=file) fclose(file);
+    time_t end_time=time(NULL);
+    fprintf(stderr, "time %.2lfsec\n", difftime(end_time, start_time));
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return ret;
+}

+ 3859 - 0
sample/opc_album.c

@@ -0,0 +1,3859 @@
+// Automatically generated by opc_generate "test_docs\helloworld.pptx" "sample\opc_album.c".
+
+#include <opc/opc.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+void writef(opcContainerOutputStream* stream, const char *s, ...) {
+    va_list ap;
+    va_start(ap, s);
+    char buf[1024];
+    int len=vsnprintf(buf, sizeof(buf), s, ap);
+    opcContainerWriteOutputStream(stream, (const opc_uint8_t *)buf, len);
+    va_end(ap);
+}
+
+void writes(opcContainerOutputStream* stream, const char *s) {
+    int const len=strlen(s);
+    opcContainerWriteOutputStream(stream, (const opc_uint8_t *)s, len);
+}
+
+static opcPart create_docProps_app_xml(opcContainer *c);
+static opcPart create_docProps_core_xml(opcContainer *c);
+static opcPart create_docProps_thumbnail_jpeg(opcContainer *c);
+static opcPart create_ppt_presProps_xml(opcContainer *c);
+static opcPart create_ppt_presentation_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout1_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout10_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout11_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout2_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout3_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout4_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout5_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout6_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout7_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout8_xml(opcContainer *c);
+static opcPart create_ppt_slideLayouts_slideLayout9_xml(opcContainer *c);
+static opcPart create_ppt_slideMasters_slideMaster1_xml(opcContainer *c);
+static opcPart create_ppt_slides_slide1_xml(opcContainer *c);
+static opcPart create_ppt_tableStyles_xml(opcContainer *c);
+static opcPart create_ppt_theme_theme1_xml(opcContainer *c);
+static opcPart create_ppt_viewProps_xml(opcContainer *c);
+
+static opcPart create_docProps_app_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("docProps/app.xml"), _X("application/vnd.openxmlformats-officedocument.extended-properties+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("docProps/app.xml"), _X("application/vnd.openxmlformats-officedocument.extended-properties+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">\n");
+              writes(out, "  <TotalTime>0</TotalTime>\n");
+              writes(out, "  <Words>5</Words>\n");
+              writes(out, "  <Application>Microsoft Office PowerPoint</Application>\n");
+              writes(out, "  <PresentationFormat>On-screen Show (4:3)</PresentationFormat>\n");
+              writes(out, "  <Paragraphs>2</Paragraphs>\n");
+              writes(out, "  <Slides>1</Slides>\n");
+              writes(out, "  <Notes>0</Notes>\n");
+              writes(out, "  <HiddenSlides>0</HiddenSlides>\n");
+              writes(out, "  <MMClips>0</MMClips>\n");
+              writes(out, "  <ScaleCrop>false</ScaleCrop>\n");
+              writes(out, "  <HeadingPairs>\n");
+              writes(out, "    <vt:vector size=\"4\" baseType=\"variant\">\n");
+              writes(out, "      <vt:variant>\n");
+              writes(out, "        <vt:lpstr>Theme</vt:lpstr>\n");
+              writes(out, "      </vt:variant>\n");
+              writes(out, "      <vt:variant>\n");
+              writes(out, "        <vt:i4>1</vt:i4>\n");
+              writes(out, "      </vt:variant>\n");
+              writes(out, "      <vt:variant>\n");
+              writes(out, "        <vt:lpstr>Slide Titles</vt:lpstr>\n");
+              writes(out, "      </vt:variant>\n");
+              writes(out, "      <vt:variant>\n");
+              writes(out, "        <vt:i4>1</vt:i4>\n");
+              writes(out, "      </vt:variant>\n");
+              writes(out, "    </vt:vector>\n");
+              writes(out, "  </HeadingPairs>\n");
+              writes(out, "  <TitlesOfParts>\n");
+              writes(out, "    <vt:vector size=\"2\" baseType=\"lpstr\">\n");
+              writes(out, "      <vt:lpstr>Office Theme</vt:lpstr>\n");
+              writes(out, "      <vt:lpstr>libOPC</vt:lpstr>\n");
+              writes(out, "    </vt:vector>\n");
+              writes(out, "  </TitlesOfParts>\n");
+              writes(out, "  <LinksUpToDate>false</LinksUpToDate>\n");
+              writes(out, "  <SharedDoc>false</SharedDoc>\n");
+              writes(out, "  <HyperlinksChanged>false</HyperlinksChanged>\n");
+              writes(out, "  <AppVersion>12.0000</AppVersion>\n");
+              writes(out, "</Properties>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+     }
+     return ret;
+}
+
+static opcPart create_docProps_core_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("docProps/core.xml"), _X("application/vnd.openxmlformats-package.core-properties+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("docProps/core.xml"), _X("application/vnd.openxmlformats-package.core-properties+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n");
+              writes(out, "  <dc:title>libOPC</dc:title>\n");
+              writes(out, "  <dc:creator>flr</dc:creator>\n");
+              writes(out, "  <cp:lastModifiedBy>flr</cp:lastModifiedBy>\n");
+              writes(out, "  <cp:revision>1</cp:revision>\n");
+              writes(out, "  <dcterms:created xsi:type=\"dcterms:W3CDTF\">2011-04-03T21:06:50Z</dcterms:created>\n");
+              writes(out, "  <dcterms:modified xsi:type=\"dcterms:W3CDTF\">2011-04-03T21:07:58Z</dcterms:modified>\n");
+              writes(out, "</cp:coreProperties>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+     }
+     return ret;
+}
+
+static opcPart create_docProps_thumbnail_jpeg(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("docProps/thumbnail.jpeg"), NULL, 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("docProps/thumbnail.jpeg"), NULL, 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              static opc_uint8_t data[]={
+                0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xDB, 0x00, 0x43, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+              , 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xC0, 0x01, 0x00, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+              , 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56
+              , 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xC4, 0x00, 0x1F, 0x01, 0x00, 0x03
+              , 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0xC4, 0x00, 0xB5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35
+              , 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA
+              , 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, 0xFE, 0xFE, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A
+              , 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A
+              , 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0x8A
+              , 0x00, 0x28, 0xA2, 0x8A, 0x00, 0x28, 0xA2, 0xBE, 0x3D, 0xFD, 0xAD, 0xBF, 0x68, 0x2F, 0x19, 0xFC, 0x05, 0xD5, 0x3F, 0x64, 0xDB, 0x1F, 0x07, 0xE9, 0x9E, 0x18, 0xD4, 0xA2, 0xF8, 0xEF, 0xFB, 0x5E, 0xFC, 0x32, 0xF8, 0x03, 0xE2, 0xF6, 0xF1, 0x2D, 0x96, 0xAB, 0x79, 0x26, 0x9D, 0xE0, 0xEF, 0x1A, 0x78, 0x5F, 0xE2, 0x0E, 0xB7, 0xAA, 0x6A, 0x5E, 0x1B, 0x3A, 0x5E, 0xB5, 0xA3, 0xAD, 0x9F, 0x89, 0xAD, 0xEE, 0xBC, 0x29, 0xA7, 0x47, 0xA7, 0xDE, 0x6A, 0x69, 0xAC, 0x69, 0x71, 0x5B, 0xCD, 0x7A, 0x97, 0x1A, 0x35, 0xD4, 0x92, 0x41, 0x2D, 0xB4, 0xF3, 0x2F, 0x6B, 0x83, 0xA3, 0xF6, 0xF1, 0xD9, 0x96, 0x57, 0x95, 0x61
+              , 0xD7, 0x47, 0x8B, 0xCE, 0x33, 0x1C, 0x2E, 0x57, 0x82, 0x53, 0x7F, 0x66, 0x9C, 0xB1, 0x78, 0xCA, 0x2A, 0xA4, 0xDE, 0x94, 0xE9, 0xB9, 0x4D, 0xA6, 0xA3, 0x60, 0x7A, 0x51, 0xC5, 0xD7, 0x7F, 0xC3, 0xC1, 0x60, 0x33, 0x1C, 0xCA, 0xBB, 0xEA, 0xB0, 0xB9, 0x5E, 0x07, 0x11, 0x98, 0xE2, 0xDC, 0x57, 0xDA, 0x9A, 0xC3, 0x61, 0x6A, 0xB8, 0x41, 0x6B, 0x39, 0xA8, 0xC1, 0x34, 0xE5, 0x73, 0xEC, 0x2A, 0x2B, 0xF2, 0x9B, 0xE2, 0x87, 0xFC, 0x14, 0x1F, 0xC6, 0xDE, 0x02, 0xD0, 0xBE, 0x1E, 0x78, 0xA7, 0x5D, 0xF0, 0x97, 0xC1, 0xBF, 0x86, 0x9E, 0x1D, 0xBE, 0xFF, 0x00, 0x82, 0x91, 0xF8, 0x87, 0xF6, 0x3D, 0xF8, 0x81, 0xAC
+              , 0x6B, 0xBF, 0x19, 0x7C, 0x21, 0xF1, 0x5B, 0x42, 0xD3, 0x7E, 0x09, 0xF8, 0x4E, 0xCF, 0xE2, 0x5D, 0xFD, 0xF7, 0xC5, 0xDD, 0x4B, 0xC4, 0xFE, 0x03, 0xF1, 0x0F, 0x87, 0xF4, 0x5F, 0x83, 0xFE, 0x36, 0xD4, 0x34, 0x8F, 0x05, 0xE9, 0xDE, 0x22, 0xD6, 0xFC, 0x01, 0xF1, 0x1A, 0x5B, 0xFD, 0x57, 0xE1, 0x3D, 0xA5, 0xC6, 0xA3, 0xA4, 0xF8, 0xEB, 0x4A, 0x9A, 0xFA, 0x35, 0xBA, 0xB6, 0xF6, 0xBF, 0x8A, 0x3F, 0xF0, 0x50, 0x7F, 0x81, 0x3A, 0x27, 0xC0, 0xDF, 0x0A, 0xFC, 0x63, 0xFD, 0x9E, 0x7C, 0x47, 0xE0, 0xFF, 0x00, 0xDB, 0x22, 0xE3, 0xE2, 0xC7, 0xC5, 0x4D, 0x23, 0xE0, 0x17, 0xC0, 0x6F, 0x0D, 0xFE, 0xCF, 0x1F, 0x14
+              , 0xBE, 0x1A, 0xF8, 0xB7, 0x46, 0xF8, 0xAD, 0xF1, 0xCB, 0xC4, 0x09, 0xA8, 0xCB, 0x67, 0xE0, 0xA8, 0xFE, 0x25, 0x5A, 0x78, 0x92, 0xEB, 0xC0, 0xBE, 0x1A, 0xD3, 0x3C, 0x39, 0xA6, 0xE8, 0xFA, 0xE7, 0x8B, 0x3E, 0x24, 0xF8, 0x8A, 0xFB, 0x52, 0xBC, 0x9B, 0xC1, 0x1E, 0x06, 0xF0, 0xDF, 0x88, 0xF5, 0xD5, 0xD0, 0xB5, 0xCD, 0x4A, 0xC6, 0xCB, 0xC3, 0xFA, 0xA4, 0x50, 0xAD, 0x0C, 0x4D, 0x08, 0xE2, 0x28, 0xB7, 0x52, 0x13, 0xC6, 0x65, 0xF8, 0x1A, 0x70, 0x84, 0x65, 0x3A, 0xF3, 0xC4, 0x66, 0xD8, 0x0E, 0x1F, 0xCC, 0x32, 0xC8, 0x2C, 0x3C, 0x14, 0xAB, 0xC6, 0x58, 0xEA, 0x5C, 0x4F, 0x94, 0x61, 0xE8, 0x52, 0xA9, 0x4E
+              , 0x15, 0xDE, 0x3E, 0xBD, 0x4C, 0x04, 0xE9, 0x43, 0x15, 0x46, 0xA5, 0x25, 0x75, 0xA0, 0xF0, 0xF8, 0x89, 0xE1, 0xAB, 0x38, 0xD3, 0x9D, 0x3C, 0x36, 0x37, 0x17, 0x52, 0x73, 0x9C, 0x23, 0x87, 0x85, 0x0C, 0xB7, 0x1D, 0x9E, 0x60, 0x33, 0x09, 0xBC, 0x4C, 0xA4, 0xA8, 0x4A, 0x9E, 0x0E, 0xA7, 0x0E, 0xE6, 0xB5, 0xEB, 0xD7, 0x85, 0x49, 0xE1, 0xD6, 0x06, 0x8C, 0x31, 0xF0, 0xAD, 0x3C, 0x25, 0x58, 0x55, 0x7F, 0x77, 0x51, 0x5F, 0x9E, 0x7E, 0x00, 0xFD, 0xB0, 0x7E, 0x36, 0x78, 0x7F, 0xF6, 0x93, 0xF8, 0x77, 0xFB, 0x30, 0x7E, 0xD8, 0x1F, 0xB3, 0xCF, 0xC3, 0xDF, 0x82, 0x5E, 0x2B, 0xF8, 0xED, 0xE0, 0xFF, 0x00, 0x1B
+              , 0x78, 0xA3, 0xF6, 0x7E, 0xF1, 0xFF, 0x00, 0xC1, 0x0F, 0xDA, 0x13, 0x5C, 0xFD, 0xA2, 0xFE, 0x14, 0x78, 0xF7, 0x5A, 0xF8, 0x5B, 0x0D, 0xAE, 0xA7, 0xF1, 0x23, 0xE1, 0x87, 0x89, 0xB5, 0x8F, 0x1B, 0xFE, 0xCF, 0xFF, 0x00, 0xB3, 0x2F, 0x8D, 0xBC, 0x09, 0xF1, 0x37, 0x4A, 0xF0, 0xB6, 0xA7, 0xA7, 0xF8, 0xE3, 0xC3, 0x1A, 0x68, 0xF8, 0x7D, 0xE2, 0x7F, 0x09, 0x78, 0xC7, 0xC2, 0x76, 0x5E, 0x2D, 0x9E, 0xD7, 0xC6, 0x9A, 0x7E, 0xB9, 0xE1, 0x5B, 0x9D, 0x06, 0xEF, 0xE7, 0x2F, 0x82, 0x9F, 0xF0, 0x54, 0x2F, 0x8D, 0x1E, 0x36, 0xB2, 0xFD, 0x99, 0xFE, 0x26, 0xFC, 0x58, 0xFD, 0x93, 0x7C, 0x03, 0xE0, 0x0F, 0xD9, 0xD3
+              , 0xF6, 0xB2, 0xF8, 0xF5, 0xE2, 0x6F, 0xD9, 0xC7, 0xE1, 0x8F, 0x8F, 0x7E, 0x1A, 0xFE, 0xD3, 0x5E, 0x22, 0xF8, 0xBF, 0xF1, 0x4B, 0xC3, 0x5F, 0x10, 0xAC, 0x3C, 0x47, 0xF1, 0x23, 0xC3, 0x7E, 0x13, 0xBF, 0xF8, 0xB1, 0xF0, 0x7F, 0xC4, 0x1F, 0xB3, 0x27, 0xC1, 0xCD, 0x13, 0xC3, 0x9E, 0x0A, 0xF1, 0x4D, 0xE7, 0xC2, 0xDF, 0x10, 0xC5, 0x7F, 0xAF, 0xF8, 0x1B, 0xE2, 0xD7, 0xC4, 0xCB, 0xFF, 0x00, 0x09, 0x4F, 0x7F, 0xA0, 0xCD, 0xAA, 0xE8, 0x33, 0x68, 0x32, 0xEB, 0xBA, 0xFF, 0x00, 0x87, 0xB4, 0x72, 0x8A, 0xA9, 0x83, 0xA4, 0xE7, 0x05, 0x2C, 0x7D, 0x48, 0xD1, 0xC2, 0xB7, 0x38, 0x2A, 0x75, 0x2B, 0xD4, 0xC7, 0x53
+              , 0xCB, 0x29, 0x61, 0xE5, 0x55, 0xCB, 0xD9, 0x52, 0xC4, 0xD6, 0xC7, 0xD5, 0xA7, 0x86, 0xA1, 0x87, 0xAD, 0x3A, 0x75, 0xEB, 0xD4, 0x9C, 0x5D, 0x2A, 0x73, 0x8B, 0xE6, 0x32, 0x94, 0xE3, 0x08, 0x62, 0x6A, 0x4A, 0xEA, 0x38, 0x4A, 0x15, 0x71, 0x58, 0x86, 0xE3, 0x2B, 0xC3, 0x0B, 0x43, 0x0B, 0x3C, 0x66, 0x23, 0x14, 0xA3, 0x6E, 0x6A, 0x98, 0x6C, 0x3E, 0x1A, 0x9D, 0x4A, 0xB8, 0x8C, 0x45, 0x25, 0x3A, 0x38, 0x75, 0x4E, 0xA4, 0x6B, 0x4E, 0x13, 0xA7, 0x38, 0xC7, 0xF6, 0x66, 0x8A, 0xFC, 0xD8, 0xF8, 0x2D, 0xFB, 0x64, 0xFE, 0xD2, 0x9F, 0xB4, 0x69, 0xF0, 0xF7, 0xC5, 0xEF, 0x82, 0xDF, 0xB2, 0x47, 0x82, 0x3C, 0x47
+              , 0xFB, 0x1B, 0x78, 0xBB, 0xC7, 0xD1, 0xF8, 0x6F, 0xC1, 0xFF, 0x00, 0x15, 0x35, 0xEF, 0xDA, 0x78, 0x78, 0x5B, 0xF6, 0x84, 0xF1, 0xAF, 0xC3, 0xC8, 0x7C, 0x4D, 0x0F, 0x83, 0x35, 0x2F, 0x8F, 0x1E, 0x14, 0xFD, 0x9E, 0x26, 0xF8, 0x1B, 0xA8, 0x7C, 0x32, 0x9F, 0xE1, 0x81, 0xD5, 0x13, 0x55, 0xF1, 0x97, 0x87, 0x2D, 0xBC, 0x43, 0xFB, 0x56, 0x78, 0x67, 0xE2, 0x27, 0x8A, 0xFE, 0x10, 0x69, 0x27, 0xC5, 0xFA, 0x67, 0x81, 0x17, 0xC6, 0x9A, 0xCF, 0x87, 0x7E, 0x17, 0xEA, 0xFF, 0x00, 0xA4, 0xF5, 0x51, 0x4E, 0x54, 0x69, 0xD6, 0xB3, 0x8C, 0x6A, 0x3B, 0x28, 0x54, 0xFD, 0xD6, 0x22, 0x2F, 0xD8, 0xD0, 0xAE, 0xD5, 0x5C
+              , 0x2D, 0x4E, 0x5C, 0x4D, 0x06, 0xA1, 0x88, 0xA7, 0x17, 0xED, 0xA9, 0x53, 0xB5, 0x78, 0xD7, 0xC3, 0x3B, 0x62, 0x30, 0xB8, 0xAA, 0x54, 0x6E, 0x4B, 0x92, 0xA4, 0xE9, 0x3B, 0x39, 0x43, 0x77, 0x06, 0xAA, 0x53, 0x7E, 0xF4, 0xA3, 0xEE, 0x56, 0x83, 0x95, 0x2A, 0x8A, 0xF0, 0x6E, 0xF4, 0xE7, 0x25, 0xCA, 0xE3, 0x2F, 0x86, 0x70, 0x72, 0x28, 0xA2, 0x8A, 0x42, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28, 0xA2, 0x80, 0x0A, 0x28
+              , 0xA2, 0x80, 0x0A, 0xF8, 0x5F, 0xF6, 0xDB, 0xF8, 0x39, 0xF1, 0x23, 0xE2, 0xEE, 0xB1, 0xFB, 0x14, 0xDD, 0x7C, 0x3C, 0xF0, 0xE7, 0xFC, 0x24, 0x36, 0xFF, 0x00, 0x09, 0x3F, 0x6E, 0x3F, 0x84, 0x5F, 0x18, 0x7E, 0x21, 0x49, 0xFD, 0xAF, 0xA0, 0xE9, 0x3F, 0xF0, 0x8F, 0xFC, 0x39, 0xF0, 0xBF, 0x84, 0x3E, 0x27, 0x69, 0x7A, 0xEF, 0x88, 0xB6, 0xEB, 0x9A, 0xA6, 0x98, 0xFA, 0xAF, 0xD8, 0x6F, 0xFC, 0x43, 0xA3, 0xC1, 0xFD, 0x91, 0xA2, 0x2E, 0xA5, 0xAE, 0xDC, 0xFD, 0xB3, 0xCD, 0xB3, 0xD3, 0x2E, 0x21, 0xB7, 0xBA, 0x92, 0x0F, 0xBA, 0x28, 0xA9, 0xE5, 0x5E, 0xDF, 0x01, 0x5F, 0x5E, 0x7C, 0xBF, 0x35, 0xC9, 0xF3, 0x8A
+              , 0x2B, 0xEC, 0xCB, 0x13, 0x92, 0x66, 0xB8, 0x3C, 0xDF, 0x0B, 0x4E, 0xAA, 0xDE, 0x54, 0x2A, 0x62, 0x70, 0x54, 0xA1, 0x88, 0x8C, 0x1C, 0x2A, 0x4E, 0x84, 0xAA, 0x46, 0x9D, 0x5A, 0x55, 0x1C, 0x6A, 0xC0, 0x97, 0xBD, 0x43, 0x1B, 0x41, 0xFC, 0x18, 0xFC, 0xB7, 0x34, 0xCA, 0xAB, 0x35, 0xF1, 0x47, 0x0F, 0x9B, 0x65, 0xD8, 0xAC, 0xB3, 0x13, 0x3A, 0x6F, 0x65, 0x5A, 0x18, 0x7C, 0x5D, 0x49, 0xD0, 0x94, 0xA3, 0x38, 0x46, 0xB4, 0x61, 0x2A, 0x94, 0xEA, 0xC1, 0x4A, 0x9C, 0xBF, 0x9E, 0x5F, 0x89, 0xDF, 0xB1, 0x67, 0xED, 0x2D, 0x2F, 0xC3, 0x41, 0xE5, 0xFE, 0xCC, 0xFA, 0x37, 0xC6, 0xAB, 0xBF, 0x0D, 0xFF, 0x00, 0xC1
+              , 0x6C, 0xBC, 0x7D, 0xFB, 0x6F, 0xBF, 0xC2, 0x6D, 0x6F, 0xC7, 0x5F, 0x08, 0x6C, 0xA2, 0xF1, 0xB7, 0xC0, 0x0B, 0x6B, 0xAF, 0x1E, 0x78, 0x83, 0xC3, 0xFE, 0x24, 0xD2, 0x6E, 0xFC, 0x5F, 0xAF, 0x5C, 0x78, 0x39, 0x7C, 0x5B, 0xAA, 0x5C, 0xDD, 0xE8, 0xAD, 0xE0, 0x7F, 0x0A, 0x78, 0xA6, 0xEF, 0x43, 0xBE, 0x87, 0xC6, 0x73, 0x68, 0x2B, 0xE2, 0xDB, 0xCF, 0x00, 0x68, 0x90, 0xEA, 0xFE, 0x32, 0xF0, 0xE4, 0x7E, 0x21, 0xFD, 0x91, 0xBF, 0x6C, 0x4F, 0x1D, 0x7C, 0x54, 0xF8, 0xA5, 0xFF, 0x00, 0x05, 0x00, 0xF0, 0xA7, 0xEC, 0xFF, 0x00, 0x07, 0xC3, 0x2F, 0x89, 0xBA, 0x3F, 0xED, 0x93, 0xFB, 0x3D, 0xFE, 0xD1, 0xFF, 0x00
+              , 0x0A, 0xFF, 0x00, 0x63, 0x6F, 0x88, 0x7F, 0x10, 0x7E, 0x14, 0xD9, 0x7C, 0x41, 0xF8, 0x8B, 0xE0, 0x8F, 0x82, 0x5F, 0xB3, 0x6F, 0x8E, 0xFF, 0x00, 0x66, 0xBF, 0x8B, 0x49, 0xE3, 0x3F, 0x1F, 0x7C, 0x2F, 0xF1, 0xCF, 0xC4, 0xDF, 0x80, 0x9E, 0x15, 0xF8, 0xD7, 0xF1, 0xAB, 0xC2, 0x5F, 0x13, 0xF5, 0xF6, 0xF8, 0x6F, 0x37, 0xFC, 0x27, 0xDE, 0x21, 0xF0, 0xED, 0x8A, 0x7C, 0x38, 0xF8, 0x53, 0x63, 0xF1, 0x27, 0xE2, 0x0F, 0x86, 0x2C, 0xF5, 0x5D, 0x66, 0x2F, 0x02, 0xFF, 0x00, 0x43, 0xD4, 0x56, 0x78, 0x1A, 0x2B, 0x01, 0x86, 0xC2, 0x61, 0xA8, 0xCE, 0x72, 0x8E, 0x02, 0x59, 0x25, 0x5C, 0x1D, 0x4A, 0x8E, 0x2E, 0xA5
+              , 0x1C, 0x46, 0x43, 0x96, 0x70, 0x4E, 0x53, 0x83, 0xAE, 0xF9, 0x23, 0x0A, 0x75, 0xFD, 0xB6, 0x13, 0x80, 0xF2, 0x85, 0x8C, 0xC3, 0x62, 0xA9, 0xD7, 0xC0, 0xE2, 0x67, 0x8A, 0xCC, 0x9B, 0xC2, 0xC6, 0x15, 0xB0, 0xB0, 0xC1, 0x5E, 0x26, 0x6B, 0x15, 0x88, 0xC5, 0xE2, 0x6A, 0x46, 0x31, 0x9E, 0x3A, 0x96, 0x79, 0x87, 0xC6, 0x46, 0x9B, 0xA9, 0x18, 0x57, 0xC2, 0x71, 0x06, 0x37, 0x8B, 0xB1, 0xD8, 0xFC, 0x2B, 0x4E, 0x72, 0x95, 0x28, 0x46, 0xB7, 0x1A, 0x66, 0xCB, 0x0D, 0x5F, 0x0F, 0x2A, 0x38, 0xCA, 0x34, 0xE8, 0xE0, 0x57, 0xD6, 0x65, 0x2A, 0x58, 0x89, 0xE2, 0xBF, 0x30, 0x34, 0xAF, 0x0B, 0x7C, 0x7F, 0xFD, 0xAB
+              , 0x7F, 0x6B, 0x4F, 0xD9, 0xAF, 0xE3, 0x8F, 0xC4, 0x7F, 0xD9, 0xC3, 0xC7, 0xBF, 0xB2, 0x8F, 0xC2, 0x1F, 0xD9, 0x26, 0xC3, 0xE3, 0x0F, 0x89, 0x34, 0x8F, 0x0D, 0xFC, 0x6B, 0xF1, 0xBF, 0xC0, 0x8F, 0x13, 0xFC, 0x5E, 0xF8, 0xAB, 0xF1, 0x93, 0xE2, 0xB7, 0x82, 0x97, 0xE1, 0x86, 0x8D, 0x71, 0xA3, 0x68, 0xDF, 0xB3, 0x6F, 0xC5, 0xCF, 0x8F, 0x9E, 0x01, 0xD0, 0x3E, 0x15, 0xF8, 0x23, 0xE1, 0xFE, 0xB3, 0xE3, 0xAB, 0x9D, 0x57, 0x55, 0xF1, 0x27, 0xC4, 0xED, 0x3F, 0xC6, 0x5E, 0x22, 0xF1, 0xA6, 0xB7, 0xA0, 0xD8, 0xD9, 0xF8, 0x0E, 0xD3, 0x41, 0xF0, 0xFD, 0xCF, 0x88, 0x35, 0x7F, 0x28, 0xFF, 0x00, 0x82, 0x74, 0x7F
+              , 0xC1, 0x32, 0xBC, 0x17, 0xF0, 0x77, 0xE0, 0xAF, 0xC2, 0xAF, 0x13, 0xFC, 0x7F, 0xF0, 0x47, 0xC4, 0x63, 0xFB, 0x46, 0xF8, 0x47, 0x5C, 0xF8, 0xF5, 0xAB, 0x59, 0x68, 0x7E, 0x3D, 0xFD, 0xA4, 0x3E, 0x2C, 0xFC, 0x64, 0xF8, 0x73, 0xF0, 0xA7, 0x53, 0xF8, 0x8F, 0xF1, 0x2F, 0xE2, 0x68, 0xB2, 0xF1, 0x77, 0xC2, 0x1F, 0x84, 0x1A, 0xCF, 0xC5, 0xDF, 0x1F, 0xFE, 0xCD, 0xFF, 0x00, 0x0A, 0xBC, 0x61, 0xAA, 0xFC, 0x34, 0xF1, 0x44, 0x56, 0x43, 0xC5, 0x5F, 0x0A, 0x7C, 0x11, 0xE1, 0xDF, 0x12, 0x59, 0x69, 0x3E, 0x28, 0xF1, 0x46, 0x87, 0x77, 0x7F, 0x6C, 0xFE, 0x25, 0xF1, 0x86, 0x9F, 0xA8, 0x7E, 0xCB, 0x51, 0x55, 0x56
+              , 0x8D, 0x1A, 0xD1, 0x50, 0x9D, 0x34, 0xBF, 0xD9, 0xB1, 0x78, 0x59, 0xCE, 0x32, 0xA8, 0xAA, 0x55, 0xA3, 0x8E, 0x9B, 0x96, 0x26, 0x33, 0xAB, 0xCF, 0xED, 0x23, 0xED, 0x21, 0xC9, 0x41, 0xAA, 0x52, 0xA7, 0x0F, 0x61, 0x46, 0x8C, 0x39, 0x6F, 0x4D, 0x48, 0xCE, 0x2A, 0x51, 0xA8, 0xEA, 0x7B, 0x49, 0x3B, 0xB8, 0x35, 0x09, 0x28, 0x3A, 0x69, 0x52, 0x4B, 0xD9, 0xAE, 0x45, 0x04, 0xA6, 0xA9, 0xCD, 0xD5, 0xA9, 0x0F, 0x6A, 0xEA, 0x38, 0xCF, 0x13, 0x88, 0xB3, 0x50, 0xA9, 0xCB, 0x1F, 0xC7, 0xCF, 0xD8, 0xA3, 0xFE, 0x1B, 0x43, 0xF6, 0x47, 0xF8, 0x33, 0xF0, 0x6F, 0xF6, 0x1D, 0xF1, 0x0F, 0xEC, 0x61, 0xE2, 0xFF, 0x00
+              , 0x89, 0x89, 0xF0, 0x32, 0xF3, 0x42, 0xF8, 0x39, 0xE1, 0x6F, 0xDA, 0xBF, 0x41, 0xF8, 0xD1, 0xFB, 0x3B, 0x78, 0x77, 0xF6, 0x6D, 0xF1, 0x4F, 0xC0, 0x9D, 0x07, 0x57, 0xB4, 0x83, 0xC3, 0xBF, 0x12, 0x7C, 0x4D, 0xA7, 0x6A, 0x7F, 0x11, 0xDB, 0xF6, 0x9F, 0xF0, 0xD7, 0xC4, 0x3D, 0x27, 0xE1, 0x73, 0x9D, 0x3F, 0x5F, 0xF8, 0x75, 0xA3, 0xFE, 0xCB, 0xFE, 0x2A, 0xD2, 0x35, 0x5F, 0x8B, 0x7A, 0x20, 0xD1, 0x74, 0xBF, 0x1E, 0x41, 0xF0, 0xFB, 0xC4, 0x07, 0xE2, 0x5E, 0x83, 0xFB, 0x07, 0x45, 0x15, 0xD3, 0x52, 0xB5, 0x5A, 0xF7, 0x9E, 0x22, 0x6F, 0x11, 0x8A, 0xA9, 0x52, 0x75, 0xB1, 0x18, 0xDA, 0xBF, 0xEF, 0x18, 0xAA
+              , 0xB5, 0x29, 0xD1, 0x8D, 0x5A, 0x95, 0xA3, 0x4F, 0xD9, 0xE1, 0x94, 0xAA, 0x56, 0xA7, 0x57, 0x17, 0x2F, 0x61, 0x87, 0xA2, 0xBD, 0xBE, 0x2F, 0x11, 0x18, 0xA8, 0xE1, 0xA3, 0x85, 0xC3, 0xE1, 0x92, 0x8C, 0x63, 0x27, 0xEC, 0xE2, 0xA9, 0xD2, 0xB5, 0xA9, 0xD0, 0x8B, 0x6E, 0x9D, 0x18, 0x29, 0x4D, 0xC6, 0x14, 0xE5, 0x37, 0x3A, 0xD2, 0x8C, 0x61, 0x28, 0xD3, 0x4E, 0xAD, 0x5A, 0xB2, 0x70, 0xA7, 0x07, 0x29, 0x4A, 0xA3, 0xA9, 0x52, 0xA1, 0x45, 0x14, 0x56, 0x45, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05
+              , 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x1E, 0x4F, 0xF1, 0xAF, 0xC5, 0x9A, 0xFF, 0x00, 0x82, 0x7C, 0x0A, 0xBE, 0x20, 0xF0, 0xCD, 0x9E, 0xA3
+              , 0xA9, 0x6A, 0xF1, 0x78, 0xD7, 0xE1, 0x86, 0x9A, 0x9A, 0x4E, 0x92, 0x9A, 0x03, 0x6A, 0x9A, 0xCD, 0x8E, 0xBF, 0xF1, 0x2F, 0xC2, 0x5A, 0x0E, 0xAF, 0xA2, 0xE9, 0xED, 0xE2, 0x8B, 0xDD, 0x33, 0x40, 0x86, 0xF3, 0x58, 0xD2, 0x75, 0x2B, 0xDD, 0x36, 0xDE, 0xEB, 0x53, 0xD5, 0x34, 0xB8, 0x2D, 0x25, 0xBA, 0x5B, 0x91, 0xA9, 0xE9, 0xD2, 0x44, 0x97, 0x90, 0xFC, 0xE3, 0x3F, 0xED, 0x3D, 0xE3, 0x9D, 0x02, 0xE7, 0xC7, 0xCB, 0xA8, 0x7C, 0x33, 0xF1, 0x65, 0xC6, 0xBB, 0x37, 0xC6, 0x1B, 0x6F, 0x05, 0xF8, 0x43, 0xC0, 0x1A, 0xFD, 0x95, 0xED, 0xFE, 0xA1, 0xE1, 0x9D, 0x16, 0xD3, 0xE0, 0xBF, 0x81, 0x7C, 0x71, 0xA9, 0xFF
+              , 0x00, 0x6C, 0x5E, 0xFE, 0xCF, 0x1E, 0x11, 0xFD, 0xA0, 0xAF, 0xEF, 0x3E, 0xD9, 0x7D, 0xA8, 0xEA, 0xBA, 0xB6, 0x9D, 0x25, 0xA6, 0x9B, 0xE2, 0x36, 0x11, 0xEA, 0xD1, 0xDB, 0x6A, 0x9A, 0x96, 0x85, 0x6B, 0x60, 0xD6, 0xD6, 0x3F, 0x48, 0x78, 0x3B, 0xE0, 0xCF, 0x82, 0x3C, 0x1A, 0xFA, 0xE4, 0xF6, 0xF6, 0x72, 0xEB, 0x97, 0x9E, 0x22, 0xD4, 0x34, 0xED, 0x57, 0x56, 0xBD, 0xF1, 0x14, 0x5A, 0x65, 0xF4, 0xB7, 0x1A, 0x96, 0x97, 0xE2, 0x4D, 0x63, 0xC6, 0xB6, 0x77, 0xC2, 0x0B, 0x6D, 0x36, 0xC6, 0xC2, 0x3B, 0xC8, 0xBC, 0x6D, 0xE2, 0x2D, 0x7F, 0xC5, 0xF1, 0x5E, 0x25, 0x98, 0xBA, 0xB5, 0xD6, 0xF5, 0x46, 0x6B, 0x29
+              , 0xAD, 0x6C, 0x34, 0xED, 0x16, 0xC7, 0x4C, 0xE8, 0x7C, 0x45, 0xF0, 0xDB, 0xE1, 0xD7, 0x8B, 0xEC, 0x75, 0x4D, 0x2F, 0xC5, 0x9E, 0x01, 0xF0, 0x57, 0x8A, 0x34, 0xCD, 0x73, 0x55, 0xB4, 0xD7, 0x35, 0xAD, 0x3B, 0xC4, 0x5E, 0x15, 0xD0, 0xB5, 0xBB, 0x1D, 0x5F, 0x5B, 0xB0, 0xB0, 0xB5, 0xD2, 0xAC, 0x75, 0x8D, 0x52, 0xD3, 0x52, 0xB0, 0xB9, 0xB7, 0xD4, 0x35, 0x5B, 0x2D, 0x2E, 0xC6, 0xCB, 0x4D, 0xB4, 0xD4, 0x2E, 0xE3, 0x9A, 0xEE, 0xDA, 0xC2, 0xCE, 0xD6, 0xCE, 0x19, 0x92, 0xDE, 0xDE, 0x28, 0xD2, 0x22, 0xA7, 0x18, 0xD6, 0xB4, 0x94, 0xA5, 0x56, 0x52, 0xE4, 0x72, 0x49, 0xAA, 0x31, 0x9D, 0x4C, 0xA1, 0xB5, 0x0B
+              , 0xA7, 0xAA, 0xA7, 0x82, 0xC7, 0x45, 0x36, 0x9A, 0x8B, 0xC6, 0x37, 0x4F, 0xD9, 0xBA, 0x98, 0x89, 0x4E, 0x93, 0x8D, 0xFD, 0xE4, 0xED, 0x17, 0x52, 0xCE, 0x3F, 0x14, 0xEF, 0x4E, 0xA4, 0x69, 0xF3, 0xA6, 0xED, 0x14, 0xA7, 0x28, 0x4D, 0xA8, 0xEA, 0x9C, 0x5A, 0x73, 0xA9, 0x1B, 0x44, 0xF0, 0x6B, 0xBF, 0x8B, 0x5E, 0x2F, 0xD4, 0x35, 0x54, 0xBA, 0xB2, 0x1A, 0xC7, 0x85, 0xEC, 0x35, 0x11, 0xFB, 0x29, 0xDE, 0xC3, 0xE1, 0x9F, 0x10, 0x68, 0x56, 0x96, 0x3A, 0xEE, 0x83, 0x17, 0xC5, 0x3F, 0x1F, 0xEB, 0xBA, 0x57, 0x8C, 0xB4, 0x7D, 0x66, 0xD3, 0x51, 0xD3, 0xFF, 0x00, 0xB4, 0x2D, 0x35, 0x49, 0xF4, 0xAB, 0x5B, 0x5D
+              , 0x26, 0xFA, 0xDE, 0xEC, 0x8B, 0x8D, 0x22, 0xE6, 0xD6, 0x47, 0xD3, 0xC5, 0x85, 0xE3, 0x4D, 0x2B, 0x75, 0x7E, 0x06, 0xF8, 0xD7, 0xAC, 0x78, 0xAF, 0xC5, 0xFA, 0x4E, 0x8D, 0xA8, 0xF8, 0x37, 0x4B, 0xD1, 0xFC, 0x35, 0xE3, 0x08, 0xBE, 0x20, 0xCD, 0xE0, 0x4D, 0x72, 0xC3, 0xC6, 0x33, 0x6B, 0xBA, 0xF5, 0xEA, 0x7C, 0x37, 0xF1, 0x05, 0xAE, 0x81, 0xAD, 0x8F, 0x18, 0xF8, 0x5C, 0xF8, 0x53, 0x49, 0xB3, 0xF0, 0x8C, 0x97, 0x52, 0xDD, 0xAC, 0xF6, 0x31, 0x69, 0xFE, 0x29, 0xF1, 0x63, 0xC0, 0xE8, 0xDA, 0x76, 0xB6, 0x34, 0x7D, 0x50, 0xAD, 0x99, 0xF6, 0x08, 0x7C, 0x1F, 0xE1, 0x2B, 0x78, 0xED, 0xE1, 0xB7, 0xF0, 0xB7
+              , 0x87, 0x20, 0x8A, 0xD6, 0x1F, 0x0E, 0xDB, 0x5A, 0xC5, 0x0E, 0x89, 0xA6, 0x45, 0x1D, 0xB5, 0xBF, 0x84, 0x27, 0x7B, 0xAF, 0x09, 0xDB, 0xDB, 0xA2, 0x5A, 0xAA, 0xC3, 0x0F, 0x85, 0xEE, 0x64, 0x92, 0xE3, 0xC3, 0xB1, 0x46, 0x16, 0x3D, 0x12, 0x79, 0x1E, 0x6D, 0x35, 0x6D, 0xA4, 0x66, 0x63, 0x47, 0x44, 0xF8, 0x77, 0xF0, 0xFF, 0x00, 0xC3, 0x5E, 0x20, 0xD7, 0x3C, 0x59, 0xE1, 0xCF, 0x02, 0xF8, 0x3B, 0x40, 0xF1, 0x4F, 0x89, 0xDD, 0xE4, 0xF1, 0x2F, 0x89, 0x74, 0x4F, 0x0C, 0xE8, 0x9A, 0x57, 0x88, 0x3C, 0x42, 0xF2, 0x4F, 0xF6, 0xA9, 0x1F, 0x5C, 0xD6, 0x6C, 0x2C, 0x60, 0xD4, 0x75, 0x67, 0x92, 0xE8, 0x9B, 0x97
+              , 0x6B, 0xFB, 0x9B, 0x82, 0xF3, 0x9F, 0x39, 0x89, 0x93, 0xE6, 0xAD, 0x93, 0x8A, 0x9D, 0x5B, 0x47, 0xF7, 0x52, 0xC5, 0x63, 0x2B, 0x41, 0x36, 0xDB, 0x85, 0x2A, 0xB8, 0x4C, 0x15, 0x0C, 0x35, 0x0D, 0x5F, 0x3D, 0xA8, 0xD6, 0xC3, 0xD7, 0xAE, 0xAD, 0x5B, 0x92, 0x32, 0xAF, 0x27, 0x2A, 0x75, 0xA5, 0x39, 0x99, 0x25, 0x3E, 0x48, 0x73, 0x49, 0x3A, 0x8A, 0x96, 0x1E, 0x13, 0xB6, 0x8A, 0x53, 0x85, 0x6C, 0x45, 0x4A, 0xD5, 0x13, 0xB3, 0x8A, 0xE7, 0x85, 0x5A, 0x70, 0xB7, 0xB2, 0xE6, 0x92, 0xA6, 0x92, 0xA9, 0x45, 0x46, 0x27, 0xC8, 0x17, 0x5F, 0x1F, 0x7C, 0x6B, 0xE1, 0x2F, 0x10, 0xD8, 0x45, 0xE2, 0x9D, 0x7A, 0x29
+              , 0xFC, 0x35, 0xF0, 0x8B, 0xC4, 0x7E, 0x34, 0xD1, 0x7E, 0x3C, 0xDD, 0x7F, 0x63, 0x69, 0x30, 0xDD, 0xDE, 0xE9, 0x5E, 0x26, 0xD5, 0xF5, 0xCD, 0x37, 0xE0, 0x8E, 0xBD, 0x94, 0x86, 0xC0, 0xE9, 0xB2, 0xDC, 0x59, 0x69, 0xFA, 0x45, 0xEE, 0xA9, 0x06, 0x8D, 0x65, 0x15, 0xA5, 0xFD, 0xCE, 0xB4, 0x89, 0x14, 0xA6, 0x28, 0x56, 0x09, 0x7B, 0xBB, 0x5F, 0x8D, 0xBF, 0x10, 0x7C, 0x2D, 0x63, 0xA2, 0x59, 0x78, 0xA3, 0xC2, 0xBA, 0x3F, 0x88, 0x66, 0xF0, 0xEE, 0x89, 0xF0, 0xA6, 0x7F, 0x8B, 0x9A, 0xFC, 0xDE, 0x29, 0x4F, 0x0F, 0x6B, 0xDA, 0x66, 0xB7, 0xF1, 0x63, 0x57, 0xFE, 0xCA, 0xB0, 0xB4, 0xF0, 0x67, 0x82, 0x34, 0xFF
+              , 0x00, 0x08, 0xEA, 0x96, 0x5E, 0x27, 0xB4, 0xD1, 0x6F, 0x65, 0x5B, 0x7B, 0xA9, 0xF5, 0x1F, 0x12, 0x78, 0x48, 0x5D, 0x47, 0x04, 0xB6, 0xDA, 0x4B, 0xEB, 0x9A, 0xB5, 0xAD, 0xF4, 0x09, 0xF4, 0x66, 0xA3, 0xE0, 0x6F, 0x04, 0xEA, 0xE9, 0xAF, 0xC5, 0xAB, 0x78, 0x3B, 0xC2, 0xDA, 0xA4, 0x7E, 0x2B, 0x93, 0x4C, 0x97, 0xC5, 0x11, 0xEA, 0x3E, 0x1F, 0xD2, 0x6F, 0x53, 0xC4, 0x92, 0xE8, 0x82, 0x05, 0xD1, 0xA4, 0xD7, 0xD2, 0xE6, 0xD2, 0x55, 0xD6, 0x24, 0xD2, 0x16, 0xD6, 0xD9, 0x74, 0xC7, 0xD4, 0x45, 0xCB, 0x58, 0x0B, 0x78, 0x05, 0xA9, 0x88, 0x45, 0x1E, 0xDA, 0xFA, 0xB7, 0xC3, 0xBF, 0x87, 0xFA, 0xFF, 0x00, 0x89
+              , 0x74, 0x6F, 0x1A, 0x6B, 0xBE, 0x05, 0xF0, 0x76, 0xB5, 0xE3, 0x1F, 0x0E, 0x22, 0x47, 0xE1, 0xEF, 0x16, 0x6A, 0xDE, 0x19, 0xD1, 0x35, 0x1F, 0x12, 0xE8, 0x29, 0x1C, 0xB3, 0x4F, 0x1A, 0x68, 0xDA, 0xED, 0xE5, 0x8C, 0xDA, 0xA6, 0x96, 0x89, 0x3D, 0xC4, 0xF3, 0x22, 0xD8, 0xDD, 0x40, 0x16, 0x59, 0xA6, 0x91, 0x40, 0x79, 0x1C, 0xB4, 0x51, 0xF7, 0x21, 0x46, 0x15, 0x7F, 0x7B, 0x28, 0xD5, 0xA3, 0x2A, 0xD5, 0x5E, 0x8E, 0x74, 0xE3, 0x4E, 0x52, 0xAF, 0x05, 0x4E, 0x3C, 0xB7, 0x55, 0x71, 0x15, 0x66, 0xE0, 0x95, 0x4A, 0x53, 0xA5, 0x87, 0xA7, 0x86, 0xA4, 0xAA, 0xB9, 0x52, 0xAB, 0x52, 0xBD, 0xD4, 0xF7, 0xA7, 0x56
+              , 0x74, 0xFF, 0x00, 0x77, 0x19, 0x42, 0xAA, 0xA7, 0x47, 0xE2, 0x51, 0x94, 0xAA, 0x42, 0x54, 0x5A, 0xAB, 0x2B, 0xC9, 0x3A, 0x54, 0xD5, 0x4A, 0x72, 0x94, 0xA1, 0x5A, 0x35, 0x39, 0xA3, 0x27, 0x49, 0x4D, 0x4A, 0x52, 0xF0, 0xAB, 0x5F, 0x8C, 0xBE, 0x36, 0xD4, 0xB5, 0x1F, 0x0A, 0x6B, 0x3A, 0x97, 0x87, 0x34, 0xFF, 0x00, 0x0A, 0x78, 0x3A, 0xEB, 0xE2, 0x57, 0xC5, 0x2F, 0x0C, 0xA4, 0x1A, 0x5F, 0x88, 0x3F, 0xE1, 0x2C, 0xD7, 0x7C, 0x59, 0xA0, 0x7C, 0x3A, 0xF0, 0xCF, 0xC5, 0x68, 0xEE, 0xAE, 0xF5, 0x3D, 0x3A, 0x7F, 0x08, 0xE8, 0xF1, 0x78, 0x62, 0x7B, 0x9D, 0x77, 0xC1, 0x36, 0x1A, 0xAE, 0x93, 0x63, 0xA3, 0x6B
+              , 0x9A, 0xE5, 0xD5, 0xD5, 0xB4, 0x89, 0x6D, 0xA8, 0x5E, 0x59, 0xFF, 0x00, 0xA4, 0x58, 0xDC, 0x73, 0x7E, 0x0C, 0xF8, 0x97, 0xF1, 0xCB, 0xE2, 0x67, 0x89, 0x7C, 0x53, 0xA7, 0x59, 0xDB, 0x78, 0x27, 0xC1, 0x26, 0x7F, 0x87, 0x1F, 0x00, 0xFC, 0x75, 0xE1, 0x9D, 0x36, 0xCF, 0xC5, 0xB1, 0x78, 0xDA, 0xC2, 0xC3, 0x40, 0xF1, 0xBF, 0x8B, 0x7C, 0x7F, 0x71, 0xE2, 0x6D, 0x56, 0x7D, 0x6F, 0xFE, 0x15, 0xE6, 0x97, 0x29, 0xF1, 0x46, 0xAD, 0xE1, 0x3D, 0x02, 0xD7, 0x49, 0x83, 0x45, 0x6B, 0x4D, 0x73, 0xC3, 0x1A, 0x7D, 0xF5, 0xA5, 0xAE, 0xA7, 0xA6, 0x6B, 0x97, 0x90, 0x5D, 0xDD, 0x4F, 0x3F, 0xD6, 0x50, 0xF8, 0x77, 0xC3
+              , 0xF6, 0xFF, 0x00, 0x60, 0xFB, 0x3E, 0x85, 0xA3, 0xC1, 0xFD, 0x95, 0x7F, 0xA9, 0x6A, 0xBA, 0x67, 0x93, 0xA6, 0x59, 0x45, 0xFD, 0x9B, 0xAA, 0x6B, 0x1F, 0xDA, 0x1F, 0xDA, 0xFA, 0x95, 0x86, 0xC8, 0x17, 0xEC, 0x77, 0xFA, 0xAF, 0xF6, 0xB6, 0xAB, 0xFD, 0xA5, 0x79, 0x6F, 0xE5, 0xDC, 0x5F, 0x7F, 0x69, 0xEA, 0x1F, 0x69, 0x92, 0x5F, 0xB6, 0xDC, 0xF9, 0x98, 0x9E, 0x12, 0xF8, 0x71, 0xF0, 0xF3, 0xC0, 0x07, 0x51, 0x3E, 0x04, 0xF0, 0x1F, 0x83, 0x3C, 0x14, 0x75, 0x79, 0x12, 0x6D, 0x58, 0xF8, 0x4B, 0xC2, 0xFA, 0x1F, 0x86, 0xCE, 0xA7, 0x2C, 0x72, 0x4F, 0x2C, 0x72, 0xEA, 0x27, 0x46, 0xB1, 0xB2, 0x37, 0xB2, 0x47
+              , 0x2D, 0xD5, 0xCC, 0x88, 0xF7, 0x3E, 0x6B, 0x24, 0x97, 0x13, 0xBA, 0x90, 0xD3, 0x48, 0x5A, 0x52, 0xD6, 0x7C, 0xEE, 0x4E, 0x3E, 0xCE, 0x82, 0xA7, 0xCA, 0xF9, 0x5C, 0x6A, 0x52, 0xF6, 0x8A, 0xB4, 0xA7, 0x65, 0x69, 0x3C, 0x4F, 0x35, 0x17, 0x26, 0x9A, 0x85, 0x2F, 0x65, 0x52, 0x34, 0xE8, 0xFE, 0xFE, 0x13, 0xC3, 0x12, 0x6F, 0xD9, 0xC9, 0x45, 0x45, 0x4E, 0x55, 0x39, 0x9B, 0x77, 0x6A, 0x30, 0xFA, 0xCE, 0x16, 0xBC, 0x61, 0x07, 0xF1, 0x46, 0x34, 0xA9, 0xD1, 0xC4, 0x50, 0x51, 0x7C, 0xD2, 0xAF, 0x0C, 0x44, 0x7D, 0xB5, 0x57, 0x1A, 0x55, 0x69, 0xE2, 0xB4, 0xFC, 0x27, 0x6F, 0xE2, 0x3B, 0x5F, 0x0C, 0x78, 0x7E
+              , 0xDF, 0xC6, 0x17, 0xF6, 0x5A, 0x9F, 0x8B, 0x22, 0xD1, 0xF4, 0xE5, 0xF1, 0x2D, 0xFE, 0x99, 0x17, 0x93, 0xA5, 0xDC, 0xEB, 0xDF, 0x65, 0x88, 0xEA, 0xD2, 0x69, 0x71, 0x1B, 0x6B, 0x37, 0x4D, 0x33, 0xED, 0xC6, 0x75, 0xD3, 0x84, 0xD6, 0xD0, 0xDC, 0x7D, 0x89, 0x60, 0x37, 0x2B, 0xF6, 0x83, 0x29, 0x3D, 0x05, 0x14, 0x55, 0xC9, 0xF3, 0x4A, 0x52, 0xB2, 0x8F, 0x33, 0x6F, 0x96, 0x2A, 0xD1, 0x57, 0x77, 0xB4, 0x56, 0xB6, 0x4B, 0x64, 0xAE, 0xEC, 0x85, 0x15, 0x68, 0xA5, 0x77, 0x2B, 0x24, 0xB9, 0xA5, 0x67, 0x27, 0x65, 0x6B, 0xBB, 0x24, 0xAE, 0xF7, 0x76, 0x49, 0x5F, 0xA2, 0x0A, 0x28, 0xA2, 0x90, 0xC2, 0x8A, 0x28
+              , 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28
+              , 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28
+              , 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x02, 0x8A, 0x28, 0xA0, 0x0F, 0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x07, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x04, 0x02
+              , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x69, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+              , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+              , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+              , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+              };
+              opcContainerWriteOutputStream(out, (const opc_uint8_t*)data, sizeof(data));
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+     }
+     return ret;
+}
+
+static opcPart create_ppt_presProps_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/presProps.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.presProps+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/presProps.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.presProps+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:presentationPr xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"/>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+     }
+     return ret;
+}
+
+static opcPart create_ppt_presentation_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/presentation.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/presentation.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:presentation xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" saveSubsetFonts=\"1\">\n");
+              writes(out, "  <p:sldMasterIdLst>\n");
+              writes(out, "    <p:sldMasterId id=\"2147483648\" r:id=\"rId1\"/>\n");
+              writes(out, "  </p:sldMasterIdLst>\n");
+              writes(out, "  <p:sldIdLst>\n");
+              writes(out, "    <p:sldId id=\"256\" r:id=\"rId2\"/>\n");
+              writes(out, "  </p:sldIdLst>\n");
+              writes(out, "  <p:sldSz cx=\"9144000\" cy=\"6858000\" type=\"screen4x3\"/>\n");
+              writes(out, "  <p:notesSz cx=\"6858000\" cy=\"9144000\"/>\n");
+              writes(out, "  <p:defaultTextStyle>\n");
+              writes(out, "    <a:defPPr>\n");
+              writes(out, "      <a:defRPr lang=\"de-DE\"/>\n");
+              writes(out, "    </a:defPPr>\n");
+              writes(out, "    <a:lvl1pPr marL=\"0\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "      <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "        <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "        <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "      </a:defRPr>\n");
+              writes(out, "    </a:lvl1pPr>\n");
+              writes(out, "    <a:lvl2pPr marL=\"457200\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "      <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "        <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "        <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "      </a:defRPr>\n");
+              writes(out, "    </a:lvl2pPr>\n");
+              writes(out, "    <a:lvl3pPr marL=\"914400\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "      <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "        <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "        <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "      </a:defRPr>\n");
+              writes(out, "    </a:lvl3pPr>\n");
+              writes(out, "    <a:lvl4pPr marL=\"1371600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "      <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "        <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "        <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "      </a:defRPr>\n");
+              writes(out, "    </a:lvl4pPr>\n");
+              writes(out, "    <a:lvl5pPr marL=\"1828800\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "      <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "        <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "        <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "      </a:defRPr>\n");
+              writes(out, "    </a:lvl5pPr>\n");
+              writes(out, "    <a:lvl6pPr marL=\"2286000\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "      <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "        <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "        <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "      </a:defRPr>\n");
+              writes(out, "    </a:lvl6pPr>\n");
+              writes(out, "    <a:lvl7pPr marL=\"2743200\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "      <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "        <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "        <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "      </a:defRPr>\n");
+              writes(out, "    </a:lvl7pPr>\n");
+              writes(out, "    <a:lvl8pPr marL=\"3200400\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "      <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "        <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "        <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "      </a:defRPr>\n");
+              writes(out, "    </a:lvl8pPr>\n");
+              writes(out, "    <a:lvl9pPr marL=\"3657600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "      <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "        <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "        <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "      </a:defRPr>\n");
+              writes(out, "    </a:lvl9pPr>\n");
+              writes(out, "  </p:defaultTextStyle>\n");
+              writes(out, "</p:presentation>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+          opcRelationAdd(c, ret, _X("rId2"), create_ppt_slides_slide1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide"));
+          opcRelationAdd(c, ret, _X("rId3"), create_ppt_presProps_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps"));
+          opcRelationAdd(c, ret, _X("rId4"), create_ppt_viewProps_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps"));
+          opcRelationAdd(c, ret, _X("rId5"), create_ppt_theme_theme1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"));
+          opcRelationAdd(c, ret, _X("rId6"), create_ppt_tableStyles_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout1_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout1.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout1.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"title\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Title Slide\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ctrTitle\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"685800\" y=\"2130425\"/>\n");
+              writes(out, "            <a:ext cx=\"7772400\" cy=\"1470025\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Subtitle 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"subTitle\" idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"1371600\" y=\"3886200\"/>\n");
+              writes(out, "            <a:ext cx=\"6400800\" cy=\"1752600\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr marL=\"0\" indent=\"0\" algn=\"ctr\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr>\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr marL=\"457200\" indent=\"0\" algn=\"ctr\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr>\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr marL=\"914400\" indent=\"0\" algn=\"ctr\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr>\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr marL=\"1371600\" indent=\"0\" algn=\"ctr\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr>\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr marL=\"1828800\" indent=\"0\" algn=\"ctr\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr>\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr marL=\"2286000\" indent=\"0\" algn=\"ctr\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr>\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr marL=\"2743200\" indent=\"0\" algn=\"ctr\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr>\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr marL=\"3200400\" indent=\"0\" algn=\"ctr\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr>\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr marL=\"3657600\" indent=\"0\" algn=\"ctr\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr>\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master subtitle style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Date Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Footer Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Slide Number Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout10_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout10.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout10.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"vertTx\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Title and Vertical Text\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Vertical Text Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"body\" orient=\"vert\" idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr vert=\"eaVert\"/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"1\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Second level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"2\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Third level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"3\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fourth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"4\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fifth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Date Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Footer Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Slide Number Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout11_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout11.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout11.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"vertTitleAndTx\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Vertical Title and Text\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Vertical Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\" orient=\"vert\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"6629400\" y=\"274638\"/>\n");
+              writes(out, "            <a:ext cx=\"2057400\" cy=\"5851525\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr vert=\"eaVert\"/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Vertical Text Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"body\" orient=\"vert\" idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"457200\" y=\"274638\"/>\n");
+              writes(out, "            <a:ext cx=\"6019800\" cy=\"5851525\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr vert=\"eaVert\"/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"1\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Second level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"2\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Third level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"3\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fourth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"4\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fifth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Date Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Footer Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Slide Number Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout2_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout2.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout2.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"obj\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Title and Content\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Content Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"1\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Second level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"2\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Third level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"3\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fourth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"4\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fifth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Date Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Footer Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Slide Number Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout3_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout3.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout3.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"secHead\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Section Header\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"722313\" y=\"4406900\"/>\n");
+              writes(out, "            <a:ext cx=\"7772400\" cy=\"1362075\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr anchor=\"t\"/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr algn=\"l\">\n");
+              writes(out, "              <a:defRPr sz=\"4000\" b=\"1\" cap=\"all\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Text Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"body\" idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"722313\" y=\"2906713\"/>\n");
+              writes(out, "            <a:ext cx=\"7772400\" cy=\"1500187\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr anchor=\"b\"/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr marL=\"0\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2000\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr marL=\"457200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1800\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr marL=\"914400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr marL=\"1371600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1400\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr marL=\"1828800\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1400\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr marL=\"2286000\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1400\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr marL=\"2743200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1400\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr marL=\"3200400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1400\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr marL=\"3657600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1400\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Date Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Footer Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Slide Number Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout4_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout4.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout4.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"twoObj\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Two Content\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Content Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph sz=\"half\" idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"457200\" y=\"1600200\"/>\n");
+              writes(out, "            <a:ext cx=\"4038600\" cy=\"4525963\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2800\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2400\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"1\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Second level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"2\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Third level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"3\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fourth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"4\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fifth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Content Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph sz=\"half\" idx=\"2\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"4648200\" y=\"1600200\"/>\n");
+              writes(out, "            <a:ext cx=\"4038600\" cy=\"4525963\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2800\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2400\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"1\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Second level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"2\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Third level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"3\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fourth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"4\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fifth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Date Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Footer Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"7\" name=\"Slide Number Placeholder 6\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout5_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout5.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout5.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"twoTxTwoObj\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Comparison\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr>\n");
+              writes(out, "              <a:defRPr/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Text Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"body\" idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"457200\" y=\"1535113\"/>\n");
+              writes(out, "            <a:ext cx=\"4040188\" cy=\"639762\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr anchor=\"b\"/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr marL=\"0\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2400\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr marL=\"457200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2000\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr marL=\"914400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1800\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr marL=\"1371600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr marL=\"1828800\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr marL=\"2286000\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr marL=\"2743200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr marL=\"3200400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr marL=\"3657600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Content Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph sz=\"half\" idx=\"2\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"457200\" y=\"2174875\"/>\n");
+              writes(out, "            <a:ext cx=\"4040188\" cy=\"3951288\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2400\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"1\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Second level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"2\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Third level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"3\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fourth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"4\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fifth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Text Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"body\" sz=\"quarter\" idx=\"3\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"4645025\" y=\"1535113\"/>\n");
+              writes(out, "            <a:ext cx=\"4041775\" cy=\"639762\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr anchor=\"b\"/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr marL=\"0\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2400\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr marL=\"457200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2000\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr marL=\"914400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1800\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr marL=\"1371600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr marL=\"1828800\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr marL=\"2286000\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr marL=\"2743200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr marL=\"3200400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr marL=\"3657600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1600\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Content Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph sz=\"quarter\" idx=\"4\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"4645025\" y=\"2174875\"/>\n");
+              writes(out, "            <a:ext cx=\"4041775\" cy=\"3951288\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2400\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1800\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr>\n");
+              writes(out, "              <a:defRPr sz=\"1600\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"1\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Second level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"2\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Third level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"3\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fourth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"4\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fifth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"7\" name=\"Date Placeholder 6\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"8\" name=\"Footer Placeholder 7\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"9\" name=\"Slide Number Placeholder 8\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout6_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout6.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout6.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"titleOnly\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Title Only\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Date Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Footer Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Slide Number Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout7_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout7.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout7.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"blank\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Blank\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Date Placeholder 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Footer Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Slide Number Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout8_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout8.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout8.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"objTx\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Content with Caption\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"457200\" y=\"273050\"/>\n");
+              writes(out, "            <a:ext cx=\"3008313\" cy=\"1162050\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr anchor=\"b\"/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr algn=\"l\">\n");
+              writes(out, "              <a:defRPr sz=\"2000\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Content Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"3575050\" y=\"273050\"/>\n");
+              writes(out, "            <a:ext cx=\"5111750\" cy=\"5853113\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr>\n");
+              writes(out, "              <a:defRPr sz=\"3200\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2800\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2400\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"1\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Second level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"2\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Third level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"3\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fourth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"4\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fifth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Text Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"body\" sz=\"half\" idx=\"2\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"457200\" y=\"1435100\"/>\n");
+              writes(out, "            <a:ext cx=\"3008313\" cy=\"4691063\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr marL=\"0\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1400\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr marL=\"457200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1200\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr marL=\"914400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1000\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr marL=\"1371600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr marL=\"1828800\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr marL=\"2286000\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr marL=\"2743200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr marL=\"3200400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr marL=\"3657600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Date Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Footer Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"7\" name=\"Slide Number Placeholder 6\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideLayouts_slideLayout9_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideLayouts/slideLayout9.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideLayouts/slideLayout9.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"picTx\" preserve=\"1\">\n");
+              writes(out, "  <p:cSld name=\"Picture with Caption\">\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"1792288\" y=\"4800600\"/>\n");
+              writes(out, "            <a:ext cx=\"5486400\" cy=\"566738\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr anchor=\"b\"/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr algn=\"l\">\n");
+              writes(out, "              <a:defRPr sz=\"2000\" b=\"1\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Picture Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"pic\" idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"1792288\" y=\"612775\"/>\n");
+              writes(out, "            <a:ext cx=\"5486400\" cy=\"4114800\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr marL=\"0\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"3200\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr marL=\"457200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2800\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr marL=\"914400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2400\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr marL=\"1371600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr marL=\"1828800\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr marL=\"2286000\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr marL=\"2743200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr marL=\"3200400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr marL=\"3657600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"2000\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Text Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"body\" sz=\"half\" idx=\"2\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"1792288\" y=\"5367338\"/>\n");
+              writes(out, "            <a:ext cx=\"5486400\" cy=\"804862\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr marL=\"0\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1400\"/>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "            <a:lvl2pPr marL=\"457200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1200\"/>\n");
+              writes(out, "            </a:lvl2pPr>\n");
+              writes(out, "            <a:lvl3pPr marL=\"914400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"1000\"/>\n");
+              writes(out, "            </a:lvl3pPr>\n");
+              writes(out, "            <a:lvl4pPr marL=\"1371600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl4pPr>\n");
+              writes(out, "            <a:lvl5pPr marL=\"1828800\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl5pPr>\n");
+              writes(out, "            <a:lvl6pPr marL=\"2286000\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl6pPr>\n");
+              writes(out, "            <a:lvl7pPr marL=\"2743200\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl7pPr>\n");
+              writes(out, "            <a:lvl8pPr marL=\"3200400\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl8pPr>\n");
+              writes(out, "            <a:lvl9pPr marL=\"3657600\" indent=\"0\">\n");
+              writes(out, "              <a:buNone/>\n");
+              writes(out, "              <a:defRPr sz=\"900\"/>\n");
+              writes(out, "            </a:lvl9pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Date Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"10\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Footer Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"11\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"7\" name=\"Slide Number Placeholder 6\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"12\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sldLayout>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideMasters_slideMaster1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slideMasters_slideMaster1_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slideMasters/slideMaster1.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slideMasters/slideMaster1.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sldMaster xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n");
+              writes(out, "  <p:cSld>\n");
+              writes(out, "    <p:bg>\n");
+              writes(out, "      <p:bgRef idx=\"1001\">\n");
+              writes(out, "        <a:schemeClr val=\"bg1\"/>\n");
+              writes(out, "      </p:bgRef>\n");
+              writes(out, "    </p:bg>\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title Placeholder 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"title\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"457200\" y=\"274638\"/>\n");
+              writes(out, "            <a:ext cx=\"8229600\" cy=\"1143000\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "          <a:prstGeom prst=\"rect\">\n");
+              writes(out, "            <a:avLst/>\n");
+              writes(out, "          </a:prstGeom>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr vert=\"horz\" lIns=\"91440\" tIns=\"45720\" rIns=\"91440\" bIns=\"45720\" rtlCol=\"0\" anchor=\"ctr\">\n");
+              writes(out, "            <a:normAutofit/>\n");
+              writes(out, "          </a:bodyPr>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master title style</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Text Placeholder 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"body\" idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"457200\" y=\"1600200\"/>\n");
+              writes(out, "            <a:ext cx=\"8229600\" cy=\"4525963\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "          <a:prstGeom prst=\"rect\">\n");
+              writes(out, "            <a:avLst/>\n");
+              writes(out, "          </a:prstGeom>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr vert=\"horz\" lIns=\"91440\" tIns=\"45720\" rIns=\"91440\" bIns=\"45720\" rtlCol=\"0\">\n");
+              writes(out, "            <a:normAutofit/>\n");
+              writes(out, "          </a:bodyPr>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"0\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Click to edit Master text styles</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"1\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Second level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"2\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Third level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"3\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fourth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:pPr lvl=\"4\"/>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"en-US\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>Fifth level</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"4\" name=\"Date Placeholder 3\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"dt\" sz=\"half\" idx=\"2\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"457200\" y=\"6356350\"/>\n");
+              writes(out, "            <a:ext cx=\"2133600\" cy=\"365125\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "          <a:prstGeom prst=\"rect\">\n");
+              writes(out, "            <a:avLst/>\n");
+              writes(out, "          </a:prstGeom>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr vert=\"horz\" lIns=\"91440\" tIns=\"45720\" rIns=\"91440\" bIns=\"45720\" rtlCol=\"0\" anchor=\"ctr\"/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr algn=\"l\">\n");
+              writes(out, "              <a:defRPr sz=\"1200\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{F6A60F8B-55A5-4810-B62A-BAFC340AFCD8}\" type=\"datetimeFigureOut\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>03.04.2011</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"5\" name=\"Footer Placeholder 4\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ftr\" sz=\"quarter\" idx=\"3\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"3124200\" y=\"6356350\"/>\n");
+              writes(out, "            <a:ext cx=\"2895600\" cy=\"365125\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "          <a:prstGeom prst=\"rect\">\n");
+              writes(out, "            <a:avLst/>\n");
+              writes(out, "          </a:prstGeom>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr vert=\"horz\" lIns=\"91440\" tIns=\"45720\" rIns=\"91440\" bIns=\"45720\" rtlCol=\"0\" anchor=\"ctr\"/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr algn=\"ctr\">\n");
+              writes(out, "              <a:defRPr sz=\"1200\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"6\" name=\"Slide Number Placeholder 5\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"sldNum\" sz=\"quarter\" idx=\"4\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr>\n");
+              writes(out, "          <a:xfrm>\n");
+              writes(out, "            <a:off x=\"6553200\" y=\"6356350\"/>\n");
+              writes(out, "            <a:ext cx=\"2133600\" cy=\"365125\"/>\n");
+              writes(out, "          </a:xfrm>\n");
+              writes(out, "          <a:prstGeom prst=\"rect\">\n");
+              writes(out, "            <a:avLst/>\n");
+              writes(out, "          </a:prstGeom>\n");
+              writes(out, "        </p:spPr>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr vert=\"horz\" lIns=\"91440\" tIns=\"45720\" rIns=\"91440\" bIns=\"45720\" rtlCol=\"0\" anchor=\"ctr\"/>\n");
+              writes(out, "          <a:lstStyle>\n");
+              writes(out, "            <a:lvl1pPr algn=\"r\">\n");
+              writes(out, "              <a:defRPr sz=\"1200\">\n");
+              writes(out, "                <a:solidFill>\n");
+              writes(out, "                  <a:schemeClr val=\"tx1\">\n");
+              writes(out, "                    <a:tint val=\"75000\"/>\n");
+              writes(out, "                  </a:schemeClr>\n");
+              writes(out, "                </a:solidFill>\n");
+              writes(out, "              </a:defRPr>\n");
+              writes(out, "            </a:lvl1pPr>\n");
+              writes(out, "          </a:lstStyle>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:fld id=\"{D1B2A4CF-930A-4403-BB03-5469F3E03291}\" type=\"slidenum\">\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x2039;#&#x203A;</a:t>\n");
+              writes(out, "            </a:fld>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMap bg1=\"lt1\" tx1=\"dk1\" bg2=\"lt2\" tx2=\"dk2\" accent1=\"accent1\" accent2=\"accent2\" accent3=\"accent3\" accent4=\"accent4\" accent5=\"accent5\" accent6=\"accent6\" hlink=\"hlink\" folHlink=\"folHlink\"/>\n");
+              writes(out, "  <p:sldLayoutIdLst>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483649\" r:id=\"rId1\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483650\" r:id=\"rId2\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483651\" r:id=\"rId3\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483652\" r:id=\"rId4\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483653\" r:id=\"rId5\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483654\" r:id=\"rId6\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483655\" r:id=\"rId7\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483656\" r:id=\"rId8\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483657\" r:id=\"rId9\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483658\" r:id=\"rId10\"/>\n");
+              writes(out, "    <p:sldLayoutId id=\"2147483659\" r:id=\"rId11\"/>\n");
+              writes(out, "  </p:sldLayoutIdLst>\n");
+              writes(out, "  <p:txStyles>\n");
+              writes(out, "    <p:titleStyle>\n");
+              writes(out, "      <a:lvl1pPr algn=\"ctr\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"0\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buNone/>\n");
+              writes(out, "        <a:defRPr sz=\"4400\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mj-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mj-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mj-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl1pPr>\n");
+              writes(out, "    </p:titleStyle>\n");
+              writes(out, "    <p:bodyStyle>\n");
+              writes(out, "      <a:lvl1pPr marL=\"342900\" indent=\"-342900\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"20000\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buFont typeface=\"Arial\" pitchFamily=\"34\" charset=\"0\"/>\n");
+              writes(out, "        <a:buChar char=\"•\"/>\n");
+              writes(out, "        <a:defRPr sz=\"3200\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl1pPr>\n");
+              writes(out, "      <a:lvl2pPr marL=\"742950\" indent=\"-285750\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"20000\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buFont typeface=\"Arial\" pitchFamily=\"34\" charset=\"0\"/>\n");
+              writes(out, "        <a:buChar char=\"–\"/>\n");
+              writes(out, "        <a:defRPr sz=\"2800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl2pPr>\n");
+              writes(out, "      <a:lvl3pPr marL=\"1143000\" indent=\"-228600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"20000\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buFont typeface=\"Arial\" pitchFamily=\"34\" charset=\"0\"/>\n");
+              writes(out, "        <a:buChar char=\"•\"/>\n");
+              writes(out, "        <a:defRPr sz=\"2400\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl3pPr>\n");
+              writes(out, "      <a:lvl4pPr marL=\"1600200\" indent=\"-228600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"20000\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buFont typeface=\"Arial\" pitchFamily=\"34\" charset=\"0\"/>\n");
+              writes(out, "        <a:buChar char=\"–\"/>\n");
+              writes(out, "        <a:defRPr sz=\"2000\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl4pPr>\n");
+              writes(out, "      <a:lvl5pPr marL=\"2057400\" indent=\"-228600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"20000\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buFont typeface=\"Arial\" pitchFamily=\"34\" charset=\"0\"/>\n");
+              writes(out, "        <a:buChar char=\"»\"/>\n");
+              writes(out, "        <a:defRPr sz=\"2000\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl5pPr>\n");
+              writes(out, "      <a:lvl6pPr marL=\"2514600\" indent=\"-228600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"20000\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buFont typeface=\"Arial\" pitchFamily=\"34\" charset=\"0\"/>\n");
+              writes(out, "        <a:buChar char=\"•\"/>\n");
+              writes(out, "        <a:defRPr sz=\"2000\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl6pPr>\n");
+              writes(out, "      <a:lvl7pPr marL=\"2971800\" indent=\"-228600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"20000\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buFont typeface=\"Arial\" pitchFamily=\"34\" charset=\"0\"/>\n");
+              writes(out, "        <a:buChar char=\"•\"/>\n");
+              writes(out, "        <a:defRPr sz=\"2000\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl7pPr>\n");
+              writes(out, "      <a:lvl8pPr marL=\"3429000\" indent=\"-228600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"20000\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buFont typeface=\"Arial\" pitchFamily=\"34\" charset=\"0\"/>\n");
+              writes(out, "        <a:buChar char=\"•\"/>\n");
+              writes(out, "        <a:defRPr sz=\"2000\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl8pPr>\n");
+              writes(out, "      <a:lvl9pPr marL=\"3886200\" indent=\"-228600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:spcBef>\n");
+              writes(out, "          <a:spcPct val=\"20000\"/>\n");
+              writes(out, "        </a:spcBef>\n");
+              writes(out, "        <a:buFont typeface=\"Arial\" pitchFamily=\"34\" charset=\"0\"/>\n");
+              writes(out, "        <a:buChar char=\"•\"/>\n");
+              writes(out, "        <a:defRPr sz=\"2000\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl9pPr>\n");
+              writes(out, "    </p:bodyStyle>\n");
+              writes(out, "    <p:otherStyle>\n");
+              writes(out, "      <a:defPPr>\n");
+              writes(out, "        <a:defRPr lang=\"de-DE\"/>\n");
+              writes(out, "      </a:defPPr>\n");
+              writes(out, "      <a:lvl1pPr marL=\"0\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl1pPr>\n");
+              writes(out, "      <a:lvl2pPr marL=\"457200\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl2pPr>\n");
+              writes(out, "      <a:lvl3pPr marL=\"914400\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl3pPr>\n");
+              writes(out, "      <a:lvl4pPr marL=\"1371600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl4pPr>\n");
+              writes(out, "      <a:lvl5pPr marL=\"1828800\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl5pPr>\n");
+              writes(out, "      <a:lvl6pPr marL=\"2286000\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl6pPr>\n");
+              writes(out, "      <a:lvl7pPr marL=\"2743200\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl7pPr>\n");
+              writes(out, "      <a:lvl8pPr marL=\"3200400\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl8pPr>\n");
+              writes(out, "      <a:lvl9pPr marL=\"3657600\" algn=\"l\" defTabSz=\"914400\" rtl=\"0\" eaLnBrk=\"1\" latinLnBrk=\"0\" hangingPunct=\"1\">\n");
+              writes(out, "        <a:defRPr sz=\"1800\" kern=\"1200\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"tx1\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:latin typeface=\"+mn-lt\"/>\n");
+              writes(out, "          <a:ea typeface=\"+mn-ea\"/>\n");
+              writes(out, "          <a:cs typeface=\"+mn-cs\"/>\n");
+              writes(out, "        </a:defRPr>\n");
+              writes(out, "      </a:lvl9pPr>\n");
+              writes(out, "    </p:otherStyle>\n");
+              writes(out, "  </p:txStyles>\n");
+              writes(out, "</p:sldMaster>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideLayouts_slideLayout1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId2"), create_ppt_slideLayouts_slideLayout2_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId3"), create_ppt_slideLayouts_slideLayout3_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId4"), create_ppt_slideLayouts_slideLayout4_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId5"), create_ppt_slideLayouts_slideLayout5_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId6"), create_ppt_slideLayouts_slideLayout6_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId7"), create_ppt_slideLayouts_slideLayout7_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId8"), create_ppt_slideLayouts_slideLayout8_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId9"), create_ppt_slideLayouts_slideLayout9_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId10"), create_ppt_slideLayouts_slideLayout10_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId11"), create_ppt_slideLayouts_slideLayout11_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+          opcRelationAdd(c, ret, _X("rId12"), create_ppt_theme_theme1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_slides_slide1_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/slides/slide1.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slide+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/slides/slide1.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.slide+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:sld xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n");
+              writes(out, "  <p:cSld>\n");
+              writes(out, "    <p:spTree>\n");
+              writes(out, "      <p:nvGrpSpPr>\n");
+              writes(out, "        <p:cNvPr id=\"1\" name=\"\"/>\n");
+              writes(out, "        <p:cNvGrpSpPr/>\n");
+              writes(out, "        <p:nvPr/>\n");
+              writes(out, "      </p:nvGrpSpPr>\n");
+              writes(out, "      <p:grpSpPr>\n");
+              writes(out, "        <a:xfrm>\n");
+              writes(out, "          <a:off x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:ext cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "          <a:chOff x=\"0\" y=\"0\"/>\n");
+              writes(out, "          <a:chExt cx=\"0\" cy=\"0\"/>\n");
+              writes(out, "        </a:xfrm>\n");
+              writes(out, "      </p:grpSpPr>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"2\" name=\"Title 1\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"ctrTitle\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" dirty=\"0\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>libOPC</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\" dirty=\"0\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "      <p:sp>\n");
+              writes(out, "        <p:nvSpPr>\n");
+              writes(out, "          <p:cNvPr id=\"3\" name=\"Subtitle 2\"/>\n");
+              writes(out, "          <p:cNvSpPr>\n");
+              writes(out, "            <a:spLocks noGrp=\"1\"/>\n");
+              writes(out, "          </p:cNvSpPr>\n");
+              writes(out, "          <p:nvPr>\n");
+              writes(out, "            <p:ph type=\"subTitle\" idx=\"1\"/>\n");
+              writes(out, "          </p:nvPr>\n");
+              writes(out, "        </p:nvSpPr>\n");
+              writes(out, "        <p:spPr/>\n");
+              writes(out, "        <p:txBody>\n");
+              writes(out, "          <a:bodyPr/>\n");
+              writes(out, "          <a:lstStyle/>\n");
+              writes(out, "          <a:p>\n");
+              writes(out, "            <a:r>\n");
+              writes(out, "              <a:rPr lang=\"de-DE\" dirty=\"0\" smtClean=\"0\"/>\n");
+              writes(out, "              <a:t>&#x201E;Hello World&#x201C;</a:t>\n");
+              writes(out, "            </a:r>\n");
+              writes(out, "            <a:endParaRPr lang=\"de-DE\" dirty=\"0\"/>\n");
+              writes(out, "          </a:p>\n");
+              writes(out, "        </p:txBody>\n");
+              writes(out, "      </p:sp>\n");
+              writes(out, "    </p:spTree>\n");
+              writes(out, "  </p:cSld>\n");
+              writes(out, "  <p:clrMapOvr>\n");
+              writes(out, "    <a:masterClrMapping/>\n");
+              writes(out, "  </p:clrMapOvr>\n");
+              writes(out, "</p:sld>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+          opcRelationAdd(c, ret, _X("rId1"), create_ppt_slideLayouts_slideLayout1_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"));
+     }
+     return ret;
+}
+
+static opcPart create_ppt_tableStyles_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/tableStyles.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/tableStyles.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<a:tblStyleLst xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" def=\"{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}\"/>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+     }
+     return ret;
+}
+
+static opcPart create_ppt_theme_theme1_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/theme/theme1.xml"), _X("application/vnd.openxmlformats-officedocument.theme+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/theme/theme1.xml"), _X("application/vnd.openxmlformats-officedocument.theme+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" name=\"Office Theme\">\n");
+              writes(out, "  <a:themeElements>\n");
+              writes(out, "    <a:clrScheme name=\"Office\">\n");
+              writes(out, "      <a:dk1>\n");
+              writes(out, "        <a:sysClr val=\"windowText\" lastClr=\"000000\"/>\n");
+              writes(out, "      </a:dk1>\n");
+              writes(out, "      <a:lt1>\n");
+              writes(out, "        <a:sysClr val=\"window\" lastClr=\"FFFFFF\"/>\n");
+              writes(out, "      </a:lt1>\n");
+              writes(out, "      <a:dk2>\n");
+              writes(out, "        <a:srgbClr val=\"1F497D\"/>\n");
+              writes(out, "      </a:dk2>\n");
+              writes(out, "      <a:lt2>\n");
+              writes(out, "        <a:srgbClr val=\"EEECE1\"/>\n");
+              writes(out, "      </a:lt2>\n");
+              writes(out, "      <a:accent1>\n");
+              writes(out, "        <a:srgbClr val=\"4F81BD\"/>\n");
+              writes(out, "      </a:accent1>\n");
+              writes(out, "      <a:accent2>\n");
+              writes(out, "        <a:srgbClr val=\"C0504D\"/>\n");
+              writes(out, "      </a:accent2>\n");
+              writes(out, "      <a:accent3>\n");
+              writes(out, "        <a:srgbClr val=\"9BBB59\"/>\n");
+              writes(out, "      </a:accent3>\n");
+              writes(out, "      <a:accent4>\n");
+              writes(out, "        <a:srgbClr val=\"8064A2\"/>\n");
+              writes(out, "      </a:accent4>\n");
+              writes(out, "      <a:accent5>\n");
+              writes(out, "        <a:srgbClr val=\"4BACC6\"/>\n");
+              writes(out, "      </a:accent5>\n");
+              writes(out, "      <a:accent6>\n");
+              writes(out, "        <a:srgbClr val=\"F79646\"/>\n");
+              writes(out, "      </a:accent6>\n");
+              writes(out, "      <a:hlink>\n");
+              writes(out, "        <a:srgbClr val=\"0000FF\"/>\n");
+              writes(out, "      </a:hlink>\n");
+              writes(out, "      <a:folHlink>\n");
+              writes(out, "        <a:srgbClr val=\"800080\"/>\n");
+              writes(out, "      </a:folHlink>\n");
+              writes(out, "    </a:clrScheme>\n");
+              writes(out, "    <a:fontScheme name=\"Office\">\n");
+              writes(out, "      <a:majorFont>\n");
+              writes(out, "        <a:latin typeface=\"Calibri\"/>\n");
+              writes(out, "        <a:ea typeface=\"\"/>\n");
+              writes(out, "        <a:cs typeface=\"\"/>\n");
+              writes(out, "        <a:font script=\"Jpan\" typeface=\"MS Pゴシック\"/>\n");
+              writes(out, "        <a:font script=\"Hang\" typeface=\"맑은 고딕\"/>\n");
+              writes(out, "        <a:font script=\"Hans\" typeface=\"宋体\"/>\n");
+              writes(out, "        <a:font script=\"Hant\" typeface=\"新細明體\"/>\n");
+              writes(out, "        <a:font script=\"Arab\" typeface=\"Times New Roman\"/>\n");
+              writes(out, "        <a:font script=\"Hebr\" typeface=\"Times New Roman\"/>\n");
+              writes(out, "        <a:font script=\"Thai\" typeface=\"Angsana New\"/>\n");
+              writes(out, "        <a:font script=\"Ethi\" typeface=\"Nyala\"/>\n");
+              writes(out, "        <a:font script=\"Beng\" typeface=\"Vrinda\"/>\n");
+              writes(out, "        <a:font script=\"Gujr\" typeface=\"Shruti\"/>\n");
+              writes(out, "        <a:font script=\"Khmr\" typeface=\"MoolBoran\"/>\n");
+              writes(out, "        <a:font script=\"Knda\" typeface=\"Tunga\"/>\n");
+              writes(out, "        <a:font script=\"Guru\" typeface=\"Raavi\"/>\n");
+              writes(out, "        <a:font script=\"Cans\" typeface=\"Euphemia\"/>\n");
+              writes(out, "        <a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/>\n");
+              writes(out, "        <a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/>\n");
+              writes(out, "        <a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/>\n");
+              writes(out, "        <a:font script=\"Thaa\" typeface=\"MV Boli\"/>\n");
+              writes(out, "        <a:font script=\"Deva\" typeface=\"Mangal\"/>\n");
+              writes(out, "        <a:font script=\"Telu\" typeface=\"Gautami\"/>\n");
+              writes(out, "        <a:font script=\"Taml\" typeface=\"Latha\"/>\n");
+              writes(out, "        <a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/>\n");
+              writes(out, "        <a:font script=\"Orya\" typeface=\"Kalinga\"/>\n");
+              writes(out, "        <a:font script=\"Mlym\" typeface=\"Kartika\"/>\n");
+              writes(out, "        <a:font script=\"Laoo\" typeface=\"DokChampa\"/>\n");
+              writes(out, "        <a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/>\n");
+              writes(out, "        <a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/>\n");
+              writes(out, "        <a:font script=\"Viet\" typeface=\"Times New Roman\"/>\n");
+              writes(out, "        <a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/>\n");
+              writes(out, "      </a:majorFont>\n");
+              writes(out, "      <a:minorFont>\n");
+              writes(out, "        <a:latin typeface=\"Calibri\"/>\n");
+              writes(out, "        <a:ea typeface=\"\"/>\n");
+              writes(out, "        <a:cs typeface=\"\"/>\n");
+              writes(out, "        <a:font script=\"Jpan\" typeface=\"MS Pゴシック\"/>\n");
+              writes(out, "        <a:font script=\"Hang\" typeface=\"맑은 고딕\"/>\n");
+              writes(out, "        <a:font script=\"Hans\" typeface=\"宋体\"/>\n");
+              writes(out, "        <a:font script=\"Hant\" typeface=\"新細明體\"/>\n");
+              writes(out, "        <a:font script=\"Arab\" typeface=\"Arial\"/>\n");
+              writes(out, "        <a:font script=\"Hebr\" typeface=\"Arial\"/>\n");
+              writes(out, "        <a:font script=\"Thai\" typeface=\"Cordia New\"/>\n");
+              writes(out, "        <a:font script=\"Ethi\" typeface=\"Nyala\"/>\n");
+              writes(out, "        <a:font script=\"Beng\" typeface=\"Vrinda\"/>\n");
+              writes(out, "        <a:font script=\"Gujr\" typeface=\"Shruti\"/>\n");
+              writes(out, "        <a:font script=\"Khmr\" typeface=\"DaunPenh\"/>\n");
+              writes(out, "        <a:font script=\"Knda\" typeface=\"Tunga\"/>\n");
+              writes(out, "        <a:font script=\"Guru\" typeface=\"Raavi\"/>\n");
+              writes(out, "        <a:font script=\"Cans\" typeface=\"Euphemia\"/>\n");
+              writes(out, "        <a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/>\n");
+              writes(out, "        <a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/>\n");
+              writes(out, "        <a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/>\n");
+              writes(out, "        <a:font script=\"Thaa\" typeface=\"MV Boli\"/>\n");
+              writes(out, "        <a:font script=\"Deva\" typeface=\"Mangal\"/>\n");
+              writes(out, "        <a:font script=\"Telu\" typeface=\"Gautami\"/>\n");
+              writes(out, "        <a:font script=\"Taml\" typeface=\"Latha\"/>\n");
+              writes(out, "        <a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/>\n");
+              writes(out, "        <a:font script=\"Orya\" typeface=\"Kalinga\"/>\n");
+              writes(out, "        <a:font script=\"Mlym\" typeface=\"Kartika\"/>\n");
+              writes(out, "        <a:font script=\"Laoo\" typeface=\"DokChampa\"/>\n");
+              writes(out, "        <a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/>\n");
+              writes(out, "        <a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/>\n");
+              writes(out, "        <a:font script=\"Viet\" typeface=\"Arial\"/>\n");
+              writes(out, "        <a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/>\n");
+              writes(out, "      </a:minorFont>\n");
+              writes(out, "    </a:fontScheme>\n");
+              writes(out, "    <a:fmtScheme name=\"Office\">\n");
+              writes(out, "      <a:fillStyleLst>\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"phClr\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:gradFill rotWithShape=\"1\">\n");
+              writes(out, "          <a:gsLst>\n");
+              writes(out, "            <a:gs pos=\"0\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:tint val=\"50000\"/>\n");
+              writes(out, "                <a:satMod val=\"300000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "            <a:gs pos=\"35000\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:tint val=\"37000\"/>\n");
+              writes(out, "                <a:satMod val=\"300000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "            <a:gs pos=\"100000\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:tint val=\"15000\"/>\n");
+              writes(out, "                <a:satMod val=\"350000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "          </a:gsLst>\n");
+              writes(out, "          <a:lin ang=\"16200000\" scaled=\"1\"/>\n");
+              writes(out, "        </a:gradFill>\n");
+              writes(out, "        <a:gradFill rotWithShape=\"1\">\n");
+              writes(out, "          <a:gsLst>\n");
+              writes(out, "            <a:gs pos=\"0\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:shade val=\"51000\"/>\n");
+              writes(out, "                <a:satMod val=\"130000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "            <a:gs pos=\"80000\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:shade val=\"93000\"/>\n");
+              writes(out, "                <a:satMod val=\"130000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "            <a:gs pos=\"100000\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:shade val=\"94000\"/>\n");
+              writes(out, "                <a:satMod val=\"135000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "          </a:gsLst>\n");
+              writes(out, "          <a:lin ang=\"16200000\" scaled=\"0\"/>\n");
+              writes(out, "        </a:gradFill>\n");
+              writes(out, "      </a:fillStyleLst>\n");
+              writes(out, "      <a:lnStyleLst>\n");
+              writes(out, "        <a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"phClr\">\n");
+              writes(out, "              <a:shade val=\"95000\"/>\n");
+              writes(out, "              <a:satMod val=\"105000\"/>\n");
+              writes(out, "            </a:schemeClr>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:prstDash val=\"solid\"/>\n");
+              writes(out, "        </a:ln>\n");
+              writes(out, "        <a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"phClr\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:prstDash val=\"solid\"/>\n");
+              writes(out, "        </a:ln>\n");
+              writes(out, "        <a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\n");
+              writes(out, "          <a:solidFill>\n");
+              writes(out, "            <a:schemeClr val=\"phClr\"/>\n");
+              writes(out, "          </a:solidFill>\n");
+              writes(out, "          <a:prstDash val=\"solid\"/>\n");
+              writes(out, "        </a:ln>\n");
+              writes(out, "      </a:lnStyleLst>\n");
+              writes(out, "      <a:effectStyleLst>\n");
+              writes(out, "        <a:effectStyle>\n");
+              writes(out, "          <a:effectLst>\n");
+              writes(out, "            <a:outerShdw blurRad=\"40000\" dist=\"20000\" dir=\"5400000\" rotWithShape=\"0\">\n");
+              writes(out, "              <a:srgbClr val=\"000000\">\n");
+              writes(out, "                <a:alpha val=\"38000\"/>\n");
+              writes(out, "              </a:srgbClr>\n");
+              writes(out, "            </a:outerShdw>\n");
+              writes(out, "          </a:effectLst>\n");
+              writes(out, "        </a:effectStyle>\n");
+              writes(out, "        <a:effectStyle>\n");
+              writes(out, "          <a:effectLst>\n");
+              writes(out, "            <a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\">\n");
+              writes(out, "              <a:srgbClr val=\"000000\">\n");
+              writes(out, "                <a:alpha val=\"35000\"/>\n");
+              writes(out, "              </a:srgbClr>\n");
+              writes(out, "            </a:outerShdw>\n");
+              writes(out, "          </a:effectLst>\n");
+              writes(out, "        </a:effectStyle>\n");
+              writes(out, "        <a:effectStyle>\n");
+              writes(out, "          <a:effectLst>\n");
+              writes(out, "            <a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\">\n");
+              writes(out, "              <a:srgbClr val=\"000000\">\n");
+              writes(out, "                <a:alpha val=\"35000\"/>\n");
+              writes(out, "              </a:srgbClr>\n");
+              writes(out, "            </a:outerShdw>\n");
+              writes(out, "          </a:effectLst>\n");
+              writes(out, "          <a:scene3d>\n");
+              writes(out, "            <a:camera prst=\"orthographicFront\">\n");
+              writes(out, "              <a:rot lat=\"0\" lon=\"0\" rev=\"0\"/>\n");
+              writes(out, "            </a:camera>\n");
+              writes(out, "            <a:lightRig rig=\"threePt\" dir=\"t\">\n");
+              writes(out, "              <a:rot lat=\"0\" lon=\"0\" rev=\"1200000\"/>\n");
+              writes(out, "            </a:lightRig>\n");
+              writes(out, "          </a:scene3d>\n");
+              writes(out, "          <a:sp3d>\n");
+              writes(out, "            <a:bevelT w=\"63500\" h=\"25400\"/>\n");
+              writes(out, "          </a:sp3d>\n");
+              writes(out, "        </a:effectStyle>\n");
+              writes(out, "      </a:effectStyleLst>\n");
+              writes(out, "      <a:bgFillStyleLst>\n");
+              writes(out, "        <a:solidFill>\n");
+              writes(out, "          <a:schemeClr val=\"phClr\"/>\n");
+              writes(out, "        </a:solidFill>\n");
+              writes(out, "        <a:gradFill rotWithShape=\"1\">\n");
+              writes(out, "          <a:gsLst>\n");
+              writes(out, "            <a:gs pos=\"0\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:tint val=\"40000\"/>\n");
+              writes(out, "                <a:satMod val=\"350000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "            <a:gs pos=\"40000\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:tint val=\"45000\"/>\n");
+              writes(out, "                <a:shade val=\"99000\"/>\n");
+              writes(out, "                <a:satMod val=\"350000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "            <a:gs pos=\"100000\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:shade val=\"20000\"/>\n");
+              writes(out, "                <a:satMod val=\"255000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "          </a:gsLst>\n");
+              writes(out, "          <a:path path=\"circle\">\n");
+              writes(out, "            <a:fillToRect l=\"50000\" t=\"-80000\" r=\"50000\" b=\"180000\"/>\n");
+              writes(out, "          </a:path>\n");
+              writes(out, "        </a:gradFill>\n");
+              writes(out, "        <a:gradFill rotWithShape=\"1\">\n");
+              writes(out, "          <a:gsLst>\n");
+              writes(out, "            <a:gs pos=\"0\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:tint val=\"80000\"/>\n");
+              writes(out, "                <a:satMod val=\"300000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "            <a:gs pos=\"100000\">\n");
+              writes(out, "              <a:schemeClr val=\"phClr\">\n");
+              writes(out, "                <a:shade val=\"30000\"/>\n");
+              writes(out, "                <a:satMod val=\"200000\"/>\n");
+              writes(out, "              </a:schemeClr>\n");
+              writes(out, "            </a:gs>\n");
+              writes(out, "          </a:gsLst>\n");
+              writes(out, "          <a:path path=\"circle\">\n");
+              writes(out, "            <a:fillToRect l=\"50000\" t=\"50000\" r=\"50000\" b=\"50000\"/>\n");
+              writes(out, "          </a:path>\n");
+              writes(out, "        </a:gradFill>\n");
+              writes(out, "      </a:bgFillStyleLst>\n");
+              writes(out, "    </a:fmtScheme>\n");
+              writes(out, "  </a:themeElements>\n");
+              writes(out, "  <a:objectDefaults/>\n");
+              writes(out, "  <a:extraClrSchemeLst/>\n");
+              writes(out, "</a:theme>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+     }
+     return ret;
+}
+
+static opcPart create_ppt_viewProps_xml(opcContainer *c) {
+     opcPart ret=opcPartFind(c, _X("ppt/viewProps.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml"), 0);
+     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X("ppt/viewProps.xml"), _X("application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml"), 0))) {
+         //adding content
+          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);
+          if (NULL!=out) {
+              writes(out, "<p:viewPr xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n");
+              writes(out, "  <p:normalViewPr>\n");
+              writes(out, "    <p:restoredLeft sz=\"15620\"/>\n");
+              writes(out, "    <p:restoredTop sz=\"94660\"/>\n");
+              writes(out, "  </p:normalViewPr>\n");
+              writes(out, "  <p:slideViewPr>\n");
+              writes(out, "    <p:cSldViewPr>\n");
+              writes(out, "      <p:cViewPr varScale=\"1\">\n");
+              writes(out, "        <p:scale>\n");
+              writes(out, "          <a:sx n=\"104\" d=\"100\"/>\n");
+              writes(out, "          <a:sy n=\"104\" d=\"100\"/>\n");
+              writes(out, "        </p:scale>\n");
+              writes(out, "        <p:origin x=\"-216\" y=\"-90\"/>\n");
+              writes(out, "      </p:cViewPr>\n");
+              writes(out, "      <p:guideLst>\n");
+              writes(out, "        <p:guide orient=\"horz\" pos=\"2160\"/>\n");
+              writes(out, "        <p:guide pos=\"2880\"/>\n");
+              writes(out, "      </p:guideLst>\n");
+              writes(out, "    </p:cSldViewPr>\n");
+              writes(out, "  </p:slideViewPr>\n");
+              writes(out, "  <p:notesTextViewPr>\n");
+              writes(out, "    <p:cViewPr>\n");
+              writes(out, "      <p:scale>\n");
+              writes(out, "        <a:sx n=\"100\" d=\"100\"/>\n");
+              writes(out, "        <a:sy n=\"100\" d=\"100\"/>\n");
+              writes(out, "      </p:scale>\n");
+              writes(out, "      <p:origin x=\"0\" y=\"0\"/>\n");
+              writes(out, "    </p:cViewPr>\n");
+              writes(out, "  </p:notesTextViewPr>\n");
+              writes(out, "  <p:gridSpacing cx=\"73736200\" cy=\"73736200\"/>\n");
+              writes(out, "</p:viewPr>\n");
+              writes(out, "");
+              opcContainerCloseOutputStream(out);
+          }
+          // adding relations
+     }
+     return ret;
+}
+
+void generate(opcContainer *c, FILE *out) {
+     // adding registered extensions
+     opcExtensionRegister(c, _X("jpeg"), _X("image/jpeg"));
+     opcExtensionRegister(c, _X("rels"), _X("application/vnd.openxmlformats-package.relationships+xml"));
+     opcExtensionRegister(c, _X("xml"), _X("application/xml"));
+     // adding root relations
+     opcRelationAdd(c, OPC_PART_INVALID, _X("rId1"), create_ppt_presentation_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"));
+     opcRelationAdd(c, OPC_PART_INVALID, _X("rId2"), create_docProps_thumbnail_jpeg(c), _X("http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"));
+     opcRelationAdd(c, OPC_PART_INVALID, _X("rId3"), create_docProps_core_xml(c), _X("http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"));
+     opcRelationAdd(c, OPC_PART_INVALID, _X("rId4"), create_docProps_app_xml(c), _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"));
+     // adding weak parts, i.e. parts which are not referenced by a relation
+}
+
+int main( int argc, const char* argv[] ) {
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    if (OPC_ERROR_NONE==opcInitLibrary() && 2==argc) {
+         opcContainer *c=NULL;
+         if (NULL!=(c=opcContainerOpen(_X(argv[1]), OPC_OPEN_WRITE_ONLY, NULL, NULL))) {
+              generate(c, stdout);
+              opcContainerClose(c, OPC_CLOSE_NOW);
+         }
+    } else if (argc!=2) {
+         printf("target file needed!\n E.g. %s \"helloworld.pptx\"", argv[0]);
+    }
+    opcFreeLibrary();
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+}

+ 283 - 0
sample/opc_changes.c

@@ -0,0 +1,283 @@
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+typedef void (paragraph_callback_t)(void *callback_ctx, int level, xmlChar *modeTxt, xmlChar *parTxt);
+
+typedef struct CHANGE_MODE {
+    opc_bool_t deleted;
+    xmlChar *mode;
+} changemode_t;
+
+static void initMode(changemode_t *mode) {
+    opc_bzero_mem(mode, sizeof(*mode));
+}
+
+static void cleanupMode(changemode_t *mode) {
+    if (NULL!=mode->mode) {
+        xmlFree(mode->mode);
+    }
+    opc_bzero_mem(mode, sizeof(*mode));
+}
+
+typedef struct PARSER_CONTEXT {
+    xmlChar *modeTxt;
+    opc_bool_t deleted;
+    xmlChar *parTxt;
+    void *callback_ctx;
+    paragraph_callback_t *callback_fct;
+} context_t;
+
+static void flush(context_t *ctx, int level) {
+    if (NULL!=ctx->callback_fct) ctx->callback_fct(ctx->callback_ctx, level, ctx->modeTxt, ctx->parTxt);
+    if (NULL!=ctx->modeTxt) xmlFree(ctx->modeTxt); ctx->modeTxt=NULL;
+    if (NULL!=ctx->parTxt) xmlFree(ctx->parTxt); ctx->parTxt=NULL;
+}
+
+static void cleanup(context_t *ctx) {
+    if (NULL!=ctx->modeTxt) xmlFree(ctx->modeTxt); ctx->modeTxt=NULL;
+    if (NULL!=ctx->parTxt) xmlFree(ctx->parTxt); ctx->parTxt=NULL;
+}
+
+static void text(context_t *ctx, const xmlChar *text, changemode_t *textMode) {
+    if (NULL!=textMode) {
+        ctx->modeTxt=xmlStrcat(ctx->modeTxt, textMode->mode);
+        ctx->modeTxt=xmlStrcat(ctx->modeTxt, _X(": \""));
+        ctx->modeTxt=xmlStrcat(ctx->modeTxt, text);
+        ctx->modeTxt=xmlStrcat(ctx->modeTxt, _X("\"\n"));
+    }
+    if (NULL!=textMode && textMode->deleted) {
+        if (!ctx->deleted) {
+            ctx->parTxt=xmlStrcat(ctx->parTxt, _X("[]"));
+        }
+        ctx->deleted=OPC_TRUE;
+    } else {
+        ctx->parTxt=xmlStrcat(ctx->parTxt, text);
+        ctx->deleted=OPC_FALSE;
+    }
+}
+
+static void par(context_t *ctx, int level, changemode_t *parMode, changemode_t *cellMode, changemode_t *rowMode) {
+    if (NULL!=rowMode && NULL!=rowMode->mode) {
+        xmlChar *modeTxt=NULL;;
+        modeTxt=xmlStrcat(modeTxt, rowMode->mode);
+        modeTxt=xmlStrcat(modeTxt, _X(": row mark\n"));
+        ctx->modeTxt=xmlStrcat(ctx->modeTxt, modeTxt);
+        xmlFree(modeTxt);
+    }
+    if (NULL!=parMode && NULL!=parMode->mode) {
+        xmlChar *modeTxt=NULL;;
+        modeTxt=xmlStrcat(modeTxt, parMode->mode);
+        modeTxt=xmlStrcat(modeTxt, _X(": paragraph mark\n"));
+        ctx->modeTxt=xmlStrcat(ctx->modeTxt, modeTxt);
+        xmlFree(modeTxt);
+    }
+    if (NULL!=parMode &&  parMode->deleted) {
+        if (!ctx->deleted) {
+            ctx->parTxt=xmlStrcat(ctx->parTxt, _X("[]"));
+        }
+        ctx->deleted=OPC_TRUE;
+    } else {
+        ctx->parTxt=xmlStrcat(ctx->parTxt, _X("\n"));
+        ctx->deleted=OPC_FALSE;
+        flush(ctx, level);
+    }
+}
+
+
+static char ns_w[]="http://schemas.openxmlformats.org/wordprocessingml/2006/main";
+
+static void dumpText(context_t *ctx, mceTextReader_t *reader, int level, changemode_t *textMode, changemode_t *parMode, changemode_t *cellMode, changemode_t *rowMode, changemode_t *prop_mode);
+static void dumpChildren(context_t *ctx, mceTextReader_t *reader, int level, changemode_t *textMode, changemode_t *parMode, changemode_t *cellMode, changemode_t *rowMode, changemode_t *prop_mode) {
+    mce_start_children(reader) {
+        mce_match_element(reader, NULL, NULL) {
+            dumpText(ctx, reader, level, textMode, parMode, cellMode, rowMode, prop_mode);
+        }
+        mce_match_text(reader) {
+            dumpText(ctx, reader, level, textMode, parMode, cellMode, rowMode, prop_mode);
+        }
+    } mce_end_children(reader);
+}
+
+
+static void dumpText(context_t *ctx, mceTextReader_t *reader, int level, changemode_t *textMode, changemode_t *parMode, changemode_t *cellMode, changemode_t *rowMode, changemode_t *prop_mode) {
+    mce_start_choice(reader) {
+        mce_start_element(reader, _X(ns_w), _X("t")) {
+            mce_skip_attributes(reader);
+            mce_start_children(reader) {
+                mce_start_text(reader) {
+                    text(ctx, xmlTextReaderConstValue(reader->reader), textMode);
+                } mce_end_text(reader);
+            } mce_end_children(reader);
+        } mce_end_element(reader);
+        mce_start_element(reader, _X(ns_w), _X("delText")) {
+            mce_skip_attributes(reader);
+            mce_start_children(reader) {
+                mce_start_text(reader) {
+                    OPC_ASSERT(NULL!=textMode && textMode->deleted);
+                    text(ctx, xmlTextReaderConstValue(reader->reader), textMode);
+                } mce_end_text(reader);
+            } mce_end_children(reader);
+        } mce_end_element(reader);
+        mce_start_element(reader, _X(ns_w), _X("ins")) {
+            changemode_t ins_props;
+            initMode(&ins_props);
+            ins_props.deleted=0;
+            ins_props.mode=xmlStrdup(_X("Insertion by "));
+            mce_start_attributes(reader) {
+                mce_start_attribute(reader, _X(ns_w), _X("author")) {
+                    ins_props.mode=xmlStrcat(ins_props.mode, xmlTextReaderConstValue(reader->reader));
+                } mce_end_attribute(reader);
+            } mce_end_attributes(reader);
+            if (NULL!=prop_mode) {
+                prop_mode->deleted=ins_props.deleted;
+                prop_mode->mode=xmlStrdup(ins_props.mode);
+            }
+            dumpChildren(ctx, reader, level, &ins_props, parMode, cellMode, rowMode, prop_mode);
+            cleanupMode(&ins_props);
+        } mce_end_element(reader);
+        mce_start_element(reader, _X(ns_w), _X("moveTo")) {
+            changemode_t ins_props;
+            initMode(&ins_props);
+            ins_props.deleted=0;
+            ins_props.mode=xmlStrdup(_X("Insertion by "));
+            mce_start_attributes(reader) {
+                mce_start_attribute(reader, _X(ns_w), _X("author")) {
+                    ins_props.mode=xmlStrcat(ins_props.mode, xmlTextReaderConstValue(reader->reader));
+                } mce_end_attribute(reader);
+            } mce_end_attributes(reader);
+            if (NULL!=prop_mode) {
+                prop_mode->deleted=ins_props.deleted;
+                prop_mode->mode=xmlStrdup(ins_props.mode);
+            }
+            dumpChildren(ctx, reader, level, &ins_props, parMode, cellMode, rowMode, prop_mode);
+            cleanupMode(&ins_props);
+        } mce_end_element(reader);
+        mce_start_element(reader, _X(ns_w), _X("del")) {
+            changemode_t del_props;
+            initMode(&del_props);
+            del_props.deleted=1;
+            del_props.mode=xmlStrdup(_X("Deletion by "));
+            mce_start_attributes(reader) {
+                mce_start_attribute(reader, _X(ns_w), _X("author")) {
+                    del_props.mode=xmlStrcat(del_props.mode, xmlTextReaderConstValue(reader->reader));
+                } mce_end_attribute(reader);
+            } mce_end_attributes(reader);
+            if (NULL!=prop_mode) {
+                prop_mode->deleted=del_props.deleted;
+                prop_mode->mode=xmlStrdup(del_props.mode);
+            }
+            dumpChildren(ctx, reader, level, &del_props, parMode, cellMode, rowMode, prop_mode);
+            cleanupMode(&del_props);
+        } mce_end_element(reader);
+        mce_start_element(reader, _X(ns_w), _X("moveFrom")) {
+            changemode_t del_props;
+            initMode(&del_props);
+            del_props.deleted=1;
+            del_props.mode=xmlStrdup(_X("Deletion by "));
+            mce_start_attributes(reader) {
+                mce_start_attribute(reader, _X(ns_w), _X("author")) {
+                    del_props.mode=xmlStrcat(del_props.mode, xmlTextReaderConstValue(reader->reader));
+                } mce_end_attribute(reader);
+            } mce_end_attributes(reader);
+            if (NULL!=prop_mode) {
+                prop_mode->deleted=del_props.deleted;
+                prop_mode->mode=xmlStrdup(del_props.mode);
+            }
+            dumpChildren(ctx, reader, level, &del_props, parMode, cellMode, rowMode, prop_mode);
+            cleanupMode(&del_props);
+        } mce_end_element(reader);
+        mce_start_element(reader, _X(ns_w), _X("p")) {
+            changemode_t p_props;
+            initMode(&p_props);
+            mce_skip_attributes(reader);
+            mce_start_children(reader) {
+                mce_match_element(reader, _X(ns_w), _X("pPr")) {
+                    dumpText(ctx, reader, level, textMode, parMode, cellMode, rowMode, &p_props);
+                };
+                mce_match_element(reader, NULL, NULL) {
+                    dumpText(ctx, reader, level, textMode, &p_props, cellMode, rowMode, NULL);
+                };
+            } mce_end_children(reader);
+            par(ctx, level, &p_props, cellMode, rowMode);
+            cleanupMode(&p_props);
+        } mce_end_element(reader);
+        mce_start_element(reader, _X(ns_w), _X("tr")) {
+            changemode_t tr_props;
+            initMode(&tr_props);
+            mce_skip_attributes(reader);
+            mce_start_children(reader) {
+                mce_match_element(reader, _X(ns_w), _X("trPr")) {
+                    dumpText(ctx, reader, level+1, textMode, parMode, cellMode, rowMode, &tr_props);
+                };
+                mce_match_element(reader, NULL, NULL) {
+                    dumpText(ctx, reader, level+1, textMode, parMode, cellMode, &tr_props, NULL);
+                };
+            } mce_end_children(reader);
+            cleanupMode(&tr_props);
+        } mce_end_element(reader);
+        mce_start_element(reader, NULL, NULL) {
+            mce_skip_attributes(reader);
+            dumpChildren(ctx, reader, level, textMode, parMode, cellMode, rowMode, prop_mode);
+        } mce_end_element(reader);
+        mce_start_text(reader) {
+        } mce_end_text(reader);
+    } mce_end_choice(reader);
+}
+
+void parseText(xmlChar *filename, paragraph_callback_t *callback_fct, void *callback_ctx) {
+    opcContainer *c=opcContainerOpen(filename, OPC_OPEN_READ_ONLY, NULL, NULL);
+    if (NULL!=c) {
+        opcRelation rel=opcRelationFind(c, OPC_PART_INVALID, NULL, _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"));
+        if (OPC_RELATION_INVALID!=rel) {
+            opcPart main=opcRelationGetInternalTarget(c, OPC_PART_INVALID, rel);
+            if (OPC_PART_INVALID!=main) {
+                const xmlChar *type=opcPartGetType(c, main);
+                if (0==xmlStrcmp(type, _X("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"))) {
+                    mceTextReader_t reader;
+                    if (OPC_ERROR_NONE==opcXmlReaderOpen(c, &reader, main, NULL, 0, 0)) {
+                        context_t ctx;
+                        opc_bzero_mem(&ctx, sizeof(ctx));
+                        ctx.callback_fct=callback_fct;
+                        ctx.callback_ctx=callback_ctx;
+                        mce_start_document(&reader) {
+                            mce_match_element(&reader, NULL, NULL) {
+                                dumpText(&ctx, &reader, 0, NULL, NULL, NULL, NULL, NULL);
+                            };
+                        } mce_end_document(&reader);
+                        flush(&ctx, 0);
+                        cleanup(&ctx);
+                    }
+                    mceTextReaderCleanup(&reader);
+                }
+            }
+        }
+        opcContainerClose(c, OPC_CLOSE_NOW);
+    }
+}
+
+static void paragraph_callback(void *callback_ctx, int level, xmlChar *modeTxt, xmlChar *parTxt) {
+    if (NULL!=modeTxt) {
+        fputs((const char *)modeTxt, (FILE*)callback_ctx);
+    }
+    if (NULL!=parTxt) {
+        fputs((const char *)parTxt, (FILE*)callback_ctx);
+    }
+}
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    opcInitLibrary();
+    parseText(_X(argv[1]), paragraph_callback, stdout);
+    opcFreeLibrary();
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return 0;
+}

+ 82 - 0
sample/opc_dump.c

@@ -0,0 +1,82 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Dump all information about an OPC container.
+
+    Ussage:
+    opc_dump FILENAME
+
+    Sample:
+    opc_dump OOXMLI1.docx
+*/
+
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    time_t start_time=time(NULL);
+    opc_error_t err=OPC_ERROR_NONE;
+    if (OPC_ERROR_NONE==opcInitLibrary()) {
+        if (2==argc) {
+            opcContainer *c=NULL;
+            if (NULL!=(c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_ONLY, NULL, NULL))) {
+                opcContainerDump(c, stdout);
+                opcContainerClose(c, OPC_CLOSE_NOW);
+            } else {
+                printf("ERROR: \"%s\" could not be opened.\n", argv[1]);
+                err=OPC_ERROR_STREAM;
+            }
+        }
+        opcFreeLibrary();
+    } else if (2==argc) {
+        printf("ERROR: initialization of libopc failed.\n");    
+        err=OPC_ERROR_STREAM;
+    } else {
+        printf("opc_dump FILENAME.\n\n");
+        printf("Sample: opc_dump test.docx\n");
+    }
+    time_t end_time=time(NULL);
+    fprintf(stderr, "time %.2lfsec\n", difftime(end_time, start_time));
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return (OPC_ERROR_NONE==err?0:3);	
+}
+

+ 96 - 0
sample/opc_extract.c

@@ -0,0 +1,96 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Extract a part from an OPC containers.
+
+    Ussage:
+    opc_extract FILENAME PARTNAME
+
+    Sample:
+    opc_extract OOXMLI1.docx "word/document.xml"
+*/
+
+
+#include <opc/opc.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+#ifdef WIN32
+    _setmode( _fileno( stdout ), _O_BINARY ); // make sure LF are not translated to CR LF on windows...
+#endif
+    if (OPC_ERROR_NONE==opcInitLibrary() && 3==argc) {
+        opcContainer *c=NULL;
+        if (NULL!=(c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_ONLY, NULL, NULL))) {
+            opcPart part=OPC_PART_INVALID;
+            if ((part=opcPartFind(c, _X(argv[2]), NULL, 0))!=OPC_PART_INVALID) {
+                opcContainerInputStream *stream=NULL;
+                if ((stream=opcContainerOpenInputStream(c, part))!=NULL){
+                    opc_uint8_t buf[100];
+                    opc_uint32_t len=0;
+                    while((len=opcContainerReadInputStream(stream, buf, sizeof(buf)))>0) {
+                        fwrite(buf, sizeof(opc_uint8_t), len, stdout);
+                    }
+                    opcContainerCloseInputStream(stream);
+                } else {
+                    fprintf(stderr, "ERROR: part \"%s\" could not be opened for reading.\n", argv[2]);
+                }
+            } else {
+                fprintf(stderr, "ERROR: part \"%s\" could not be opened in \"%s\".\n", argv[2], argv[1]);
+            }
+            opcContainerClose(c, OPC_CLOSE_NOW);
+        } else {
+            fprintf(stderr, "ERROR: file \"%s\" could not be opened.\n", argv[1]);
+        }
+        opcFreeLibrary();
+    } else if (2==argc) {
+        fprintf(stderr, "ERROR: initialization of libopc failed.\n");    
+    } else {
+        fprintf(stderr, "opc_extract FILENAME PART\n\n");
+        fprintf(stderr, "Sample: opc_extract test.docx word/document.xml\n");
+    }
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return 0;
+}

+ 370 - 0
sample/opc_generate.c

@@ -0,0 +1,370 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Generates "C" code from an OPC container template. The generated "C" code will then prgrammatically generate the container again.
+    Very useful for generating boilerplate code.
+
+    Ussage:
+    opc_generate FILENAME OUTNAME
+
+    Sample:
+    opc_generate helloworld.pptx helloworld.c
+*/
+
+
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#include <libxml/xmlsave.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+static void add_visited_part(opcPart **visited_parts_array, opc_uint32_t *visited_parts_count, opcPart part) {
+    *visited_parts_array=(opcPart*)xmlRealloc(*visited_parts_array, sizeof(opcPart)*(*visited_parts_count+1));
+    (*visited_parts_array)[(*visited_parts_count)++]=part;
+}
+
+static opc_bool_t is_visited_part(opcPart *visited_parts_array, opc_uint32_t visited_parts_count, opcPart part) {
+    for(opc_uint32_t i=0;i<visited_parts_count;i++) {
+        if (visited_parts_array[i]==part) {
+            return OPC_TRUE;
+        }
+    }
+    return OPC_FALSE;
+}
+
+
+static void normalize_name(char *dest, const xmlChar *src, opc_uint32_t len) {
+    opc_uint32_t i=0;
+    opc_uint32_t j=0;
+    while(j<len && 0!=src[i]) {
+        if (src[i]=='/' || src[i]=='.' || src[i]=='-' || src[i]=='_' || src[i]=='[' || src[i]==']') {
+            dest[j++]='_'; i++;
+        } else if ((src[i]>='A' && src[i]<='Z') || (src[i]>='a' && src[i]<='z') || (src[i]>='0' && src[i]<='9')) {
+            dest[j++]=src[i++];
+        } else {
+            j+=snprintf(dest+j, len-j, "x%02X", src[i++]);
+        }
+    }
+    if (j<len) dest[j]=0; else if (j>0) dest[j-1]=0;
+}
+
+static xmlChar *xmlStrEscape(const xmlChar *str) {
+    opc_uint32_t i=0;
+    opc_uint32_t a=0;
+    for(;str[i]!=0;i++) {
+        if ('\\'==str[i]) {
+            a++;
+        }
+    }
+    if (0==a) {
+        return xmlStrdup(str);
+    } else {
+        xmlChar *ret = (xmlChar *) xmlMalloc((i + a + 1) * sizeof(xmlChar));
+        for(opc_uint32_t j=0, k=0;j<=i;j++) {
+            if ('\\'==str[j]) { ret[k++]='\\'; ret[k++]='\\';} else ret[k++]=str[j];
+        }
+        return ret;
+    }
+}
+
+static void generate_relations(opcContainer *c, FILE *out, opcPart root) {
+    for(opcRelation rel=opcRelationFirst(c, root)
+       ;OPC_RELATION_INVALID!=rel
+       ;rel=opcRelationNext(c, root, rel)) {
+            const xmlChar *prefix=NULL;
+            opc_uint32_t counter=-1;
+            const xmlChar *type=NULL;
+            opcRelationGetInformation(c, root, rel, &prefix, &counter, &type);
+            char buf[20]="";
+            if (-1!=counter) {
+                sprintf(buf, "%i", counter);
+            }
+            opcPart internal_target=opcRelationGetInternalTarget(c, root, rel);
+            if (OPC_PART_INVALID!=internal_target) {
+                char part[OPC_MAX_PATH]="";
+                normalize_name(part, internal_target, sizeof(part));
+                fprintf(out, "     %sopcRelationAdd(c, %s, _X(\"%s%s\"), create_%s(c), _X(\"%s\"));\n", 
+                    (OPC_PART_INVALID==root?"":"     "), 
+                    (OPC_PART_INVALID==root?"OPC_PART_INVALID":"ret"), 
+                    prefix, buf, part, type);
+            } else {
+                xmlChar *external_target=xmlStrEscape(opcRelationGetExternalTarget(c, root, rel));
+                if (NULL!=external_target) {
+                    fprintf(out, "     %sopcRelationAddExternal(c, %s, _X(\"%s%s\"), _X(\"%s\"), _X(\"%s\"));\n", 
+                        (OPC_PART_INVALID==root?"":"     "), 
+                        (OPC_PART_INVALID==root?"OPC_PART_INVALID":"ret"), 
+                        prefix, buf,
+                        external_target,
+                        type);
+                }
+                xmlFree(external_target);
+            }
+    }
+}
+
+static void generate_binary_data(opcContainer *c, FILE *out, opcContainerInputStream *in) {
+    fprintf(out, "              static opc_uint8_t data[]={\n");
+    opc_uint8_t buf[100];
+    opc_uint32_t len=0;
+    char cont=' ';
+    while((len=opcContainerReadInputStream(in, buf, sizeof(buf)))>0) {
+        fprintf(out, "              ");
+        for(opc_uint32_t i=0;i<len;i++) {
+            fprintf(out, "%c 0x%02X", cont, buf[i]);
+            cont=',';
+        }
+        fprintf(out, "\n");
+    }
+    fprintf(out, "              };\n");
+}
+
+static int  xmlOutputWrite(void * context, const char * buffer, int len) {
+    FILE *out=(FILE*)context;
+    for(int i=0;i<len;i++) {
+        switch(buffer[i]) {
+        case '\n':
+            fprintf(out, "\\n\");\n              writes(out, \"");
+        case '\r':
+            break;
+        case '"':
+            fprintf(out, "\\\"");
+            break;
+        case '\\':
+            fprintf(out, "\\\\");
+            break;
+        default:
+            putc(buffer[i], out);
+        }
+    }
+    return len;
+}
+
+static int xmlOutputClose(void * context) {
+    return 0;
+}
+
+static void generate_xml_data(opcContainer *c, FILE *out, opcPart part) {
+    fprintf(out, "              writes(out, \"");
+    xmlDocPtr doc=opcXmlReaderReadDoc(c, part, NULL, NULL, 0);
+    if (NULL!=doc) {
+        xmlSaveCtxtPtr save=xmlSaveToIO(xmlOutputWrite, xmlOutputClose, out, NULL, XML_SAVE_FORMAT | XML_SAVE_NO_DECL);
+        if (NULL!=save) {
+            xmlSaveDoc(save, doc);
+            xmlSaveClose(save);
+        }
+        xmlFreeDoc(doc);
+    }
+    fprintf(out, "\");\n");
+}
+
+
+static void generate_parts(opcContainer *c, FILE *out) {
+    for(opcPart part=opcPartGetFirst(c);OPC_PART_INVALID!=part;part=opcPartGetNext(c, part)) {
+            char norm_part[OPC_MAX_PATH]="";
+            normalize_name(norm_part, part, sizeof(norm_part));
+            fprintf(out, "static opcPart create_%s(opcContainer *c);\n", norm_part);
+    }
+    fprintf(out, "\n");
+    for(opcPart part=opcPartGetFirst(c);OPC_PART_INVALID!=part;part=opcPartGetNext(c, part)) {
+            char norm_part[OPC_MAX_PATH]="";
+            normalize_name(norm_part, part, sizeof(norm_part));
+            const xmlChar *override_type=opcPartGetTypeEx(c, part, OPC_TRUE);
+            fprintf(out, "static opcPart create_%s(opcContainer *c) {\n", norm_part);
+            if (NULL!=override_type) {
+                fprintf(out, "     opcPart ret=opcPartFind(c, _X(\"%s\"), _X(\"%s\"), 0);\n", part, override_type);
+            } else {
+                fprintf(out, "     opcPart ret=opcPartFind(c, _X(\"%s\"), NULL, 0);\n", part);
+            }
+            if (NULL!=override_type) {
+                fprintf(out, "     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X(\"%s\"), _X(\"%s\"), 0))) {\n", part, override_type);
+            } else {
+                fprintf(out, "     if (OPC_PART_INVALID==ret && OPC_PART_INVALID!=(ret=opcPartCreate(c, _X(\"%s\"), NULL, 0))) {\n", part);
+            }
+            fprintf(out, "         //adding content\n");
+            fprintf(out, "          opcContainerOutputStream *out=opcContainerCreateOutputStream(c, ret, OPC_COMPRESSIONOPTION_NORMAL);\n");
+            fprintf(out, "          if (NULL!=out) {\n");
+            const xmlChar *type=opcPartGetType(c, part);
+            opc_uint32_t type_len=(NULL!=type?xmlStrlen(type):0);
+            if (type_len>0 && type[type_len-3]=='x' && type[type_len-2]=='m' && type[type_len-1]=='l') {
+                generate_xml_data(c, out, part);
+            } else {
+                if (opcPartGetSize(c, part)>0) {
+                    opcContainerInputStream *in=opcContainerOpenInputStream(c, part);
+                    if (NULL!=in) {
+                        generate_binary_data(c, out, in);
+                        fprintf(out, "              opcContainerWriteOutputStream(out, (const opc_uint8_t*)data, sizeof(data));\n");
+                    }
+                    opcContainerCloseInputStream(in);
+                }
+            }
+            fprintf(out, "              opcContainerCloseOutputStream(out);\n");
+            fprintf(out, "          }\n");
+
+            fprintf(out, "          // adding relations\n");
+            generate_relations(c, out, part);
+            fprintf(out, "     }\n");
+            fprintf(out, "     return ret;\n");
+            fprintf(out, "}\n");
+            fprintf(out, "\n");
+    }
+}
+
+
+static void visit_all_parts(opcContainer *c, opcPart root, opcPart **visited_parts_array, opc_uint32_t *visited_parts_count) {
+    for(opcRelation rel=opcRelationFirst(c, root)
+       ;OPC_RELATION_INVALID!=rel
+       ;rel=opcRelationNext(c, root, rel)) {
+           opcPart part=opcRelationGetInternalTarget(c, root, rel);
+           if (OPC_PART_INVALID!=part) {
+               if (!is_visited_part(*visited_parts_array, *visited_parts_count, part)) {
+                   add_visited_part(visited_parts_array, visited_parts_count, part);
+                   visit_all_parts(c, part, visited_parts_array, visited_parts_count);
+               }
+           }
+    }
+}
+
+static void generate_weak_parts(opcContainer *c, FILE *out) {
+    opcPart *visited_parts_array=NULL;
+    opc_uint32_t visited_parts_count=0;
+    visit_all_parts(c, OPC_PART_INVALID, &visited_parts_array, &visited_parts_count);
+    for(opcPart part=opcPartGetFirst(c);OPC_PART_INVALID!=part;part=opcPartGetNext(c, part)) {
+        if (!is_visited_part(visited_parts_array, visited_parts_count, part)) {
+            char _part[OPC_MAX_PATH]="";
+            normalize_name(_part, part, sizeof(_part));
+            fprintf(out, "     create_%s(c);\n", _part);
+        }
+    }
+    if (NULL!=visited_parts_array) {
+        xmlFree(visited_parts_array);
+    }
+}
+
+
+static void generate(opcContainer *c, FILE *out, const char *template_name, const char *out_name) {
+    fprintf(out, "// Automatically generated by opc_generate \"%s\" \"%s\".\n", template_name, out_name);
+    fprintf(out, "\n");
+    fprintf(out, "#include <opc/opc.h>\n");
+    fprintf(out, "#ifdef WIN32\n");
+    fprintf(out, "#include <crtdbg.h>\n");
+    fprintf(out, "#endif\n");
+    fprintf(out, "\n");
+    fprintf(out, "void writef(opcContainerOutputStream* stream, const char *s, ...) {\n");
+    fprintf(out, "    va_list ap;\n");
+    fprintf(out, "    va_start(ap, s);\n");
+    fprintf(out, "    char buf[1024];\n");
+    fprintf(out, "    int len=vsnprintf(buf, sizeof(buf), s, ap);\n");
+    fprintf(out, "    opcContainerWriteOutputStream(stream, (const opc_uint8_t *)buf, len);\n");
+    fprintf(out, "    va_end(ap);\n");
+    fprintf(out, "}\n");
+    fprintf(out, "\n");
+    fprintf(out, "void writes(opcContainerOutputStream* stream, const char *s) {\n");
+    fprintf(out, "    int const len=strlen(s);\n");
+    fprintf(out, "    opcContainerWriteOutputStream(stream, (const opc_uint8_t *)s, len);\n");
+    fprintf(out, "}\n");
+    fprintf(out, "\n");
+    generate_parts(c, out);
+    fprintf(out, "void generate(opcContainer *c, FILE *out) {\n");
+    fprintf(out, "     // adding registered extensions\n");
+    for(const xmlChar *ext=opcExtensionFirst(c);NULL!=ext;ext=opcExtensionNext(c, ext)) {
+        const xmlChar *type=opcExtensionGetType(c, ext);
+        fprintf(out, "     opcExtensionRegister(c, _X(\"%s\"), _X(\"%s\"));\n", ext, type);
+    }
+    fprintf(out, "     // adding root relations\n");
+    generate_relations(c, out, OPC_PART_INVALID);
+    fprintf(out, "     // adding weak parts, i.e. parts which are not referenced by a relation\n");
+    generate_weak_parts(c, out);
+    fprintf(out, "}\n");
+    fprintf(out, "\n");
+    fprintf(out, "int main( int argc, const char* argv[] ) {\n");
+    fprintf(out, "#ifdef WIN32\n");
+    fprintf(out, "     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);\n");
+    fprintf(out, "#endif\n");
+    fprintf(out, "    if (OPC_ERROR_NONE==opcInitLibrary() && 2==argc) {\n");
+    fprintf(out, "         opcContainer *c=NULL;\n");
+    fprintf(out, "         if (NULL!=(c=opcContainerOpen(_X(argv[1]), OPC_OPEN_WRITE_ONLY, NULL, NULL))) {\n");
+    fprintf(out, "              generate(c, stdout);\n");
+    fprintf(out, "              opcContainerClose(c, OPC_CLOSE_NOW);\n");
+    fprintf(out, "         }\n");
+    fprintf(out, "    } else if (argc!=2) {\n");
+    int ofs=strlen(template_name); while(ofs>0 && template_name[ofs-1]!='/' && template_name[ofs-1]!='\\') ofs--;
+    fprintf(out, "         printf(\"target file needed!\\n E.g. %%s \\\"%s\\\"\", argv[0]);\n", template_name+ofs);
+    fprintf(out, "    }\n");
+    fprintf(out, "    opcFreeLibrary();\n");
+    fprintf(out, "#ifdef WIN32\n");
+    fprintf(out, "    OPC_ASSERT(!_CrtDumpMemoryLeaks());\n");
+    fprintf(out, "#endif\n");
+    fprintf(out, "}\n");
+}
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+    time_t start_time=time(NULL);
+    opc_error_t err=OPC_ERROR_NONE;
+    if (OPC_ERROR_NONE==opcInitLibrary() && argc>=2) {
+        opcContainer *c=NULL;
+        if (NULL!=(c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_ONLY, NULL, NULL))) {
+            FILE *out=stdout;
+            if (argc>=3) {
+                out=fopen(argv[2], "w");
+            }
+            generate(c, out, argv[1], argv[2]);
+            if (stdout!=out) {
+                fclose(out);
+            }
+            opcContainerClose(c, OPC_CLOSE_NOW);
+        } else {
+            printf("ERROR: \"%s\" could not be opened.\n", argv[1]);
+            err=OPC_ERROR_STREAM;
+        }
+        opcFreeLibrary();
+    } else if (2==argc) {
+        printf("ERROR: initialization of libopc failed.\n");    
+        err=OPC_ERROR_STREAM;
+    } else {
+        printf("opc_generate CONTAINERNAME CFILENAME\n\n");
+        printf("Sample: opc_generate test.docx test.c\n");
+    }
+    time_t end_time=time(NULL);
+    fprintf(stderr, "time %.2lfsec\n", difftime(end_time, start_time));
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return (OPC_ERROR_NONE==err?0:3);	
+}
+

+ 65 - 0
sample/opc_helloworld.c

@@ -0,0 +1,65 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Simple demonstration program of how to initialize the library.
+
+    Ussage:
+    opc_helloworld
+
+    Sample:
+    opc_helloworld
+*/
+
+#include <opc/opc.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+	if (OPC_ERROR_NONE==opcInitLibrary()) {
+		printf("libopc as well as zlib and libxml2 are ready to use.\n");
+		opcFreeLibrary();
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+		return 0;
+	}  else  {
+		printf("error initializing libopc.\n ");
+		return 1;
+	}
+}
+

+ 100 - 0
sample/opc_image.c

@@ -0,0 +1,100 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Extract all images from an OPC container.
+
+    Ussage:
+    opc_image FILENAME [OUTPATH]
+
+    The OUTPATH must exist.
+
+    Sample:
+    opc_image OOXMLI1.docx C:\Users\flr\Pictures
+*/
+
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+static void extract(opcContainer *c, opcPart p, const char *path) {
+    char filename[OPC_MAX_PATH];
+    opc_uint32_t i=xmlStrlen(p);
+    while(i>0 && p[i]!='/') i--;
+    if (p[i]=='/') i++;    
+    strcpy(filename, path);
+    strcat(filename,  (char *)(p+i));    
+    FILE *out=fopen(filename, "wb");
+    if (NULL!=out) {
+        opcContainerInputStream *stream=opcContainerOpenInputStream(c, p);
+        if (NULL!=stream) {
+            opc_uint32_t  ret=0;
+            opc_uint8_t buf[100];
+            while((ret=opcContainerReadInputStream(stream, buf, sizeof(buf)))>0) {
+                fwrite(buf, sizeof(char), ret, out);
+            }
+            opcContainerCloseInputStream(stream);
+        }
+        fclose(out);
+    }
+}
+
+int main( int argc, const char* argv[] )
+{    
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    opcInitLibrary();
+    opcContainer *c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_ONLY, NULL, NULL);
+    const char *path=(argc>1?argv[2]:"");
+    if (NULL!=c) {
+        for(opcPart part=opcPartGetFirst(c);OPC_PART_INVALID!=part;part=opcPartGetNext(c, part)) {
+            const xmlChar *type=opcPartGetType(c, part);
+            if (xmlStrcmp(type, _X("image/jpeg"))==0) {
+                extract(c, part, path);
+            } else if (xmlStrcmp(type, _X("image/png"))==0) {
+                extract(c, part, path);
+            } else {
+                printf("skipped %s of type %s\n", part, type);
+            }
+        }
+        opcContainerClose(c, OPC_CLOSE_NOW);
+    }
+    opcFreeLibrary();
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return 0;
+}
+

+ 89 - 0
sample/opc_mem.c

@@ -0,0 +1,89 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Dump all information about an OPC container via the memory-based OPC container interface.
+
+    Ussage:
+    opc_mem FILENAME
+
+    Sample:
+    opc_mem OOXMLI1.docx
+*/
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    time_t start_time=time(NULL);
+    opc_error_t err=OPC_ERROR_NONE;
+    if (OPC_ERROR_NONE==opcInitLibrary() && 2==argc) {
+        opcContainer *c=NULL;
+        FILE *f=fopen(argv[1], "rb");
+        fseek(f, 0, SEEK_END);
+        opc_uint32_t data_len=ftell(f);
+        fseek(f, 0, SEEK_SET);
+        opc_uint8_t *data=(opc_uint8_t *)xmlMalloc(data_len);
+        size_t fread_len=fread(data, 1, data_len, f);
+        fclose(f);
+	if (data_len!=fread_len) {
+            printf("ERROR: reading file.\n");
+	} else if (NULL!=(c=opcContainerOpenMem(data, data_len, OPC_OPEN_READ_ONLY, NULL))) {
+            opcContainerDump(c, stdout);
+            opcContainerClose(c, OPC_CLOSE_NOW);
+        } else {
+            printf("ERROR: \"%s\" could not be opened.\n", argv[1]);
+            err=OPC_ERROR_STREAM;
+        }
+        xmlFree(data);
+        opcFreeLibrary();
+    } else if (2==argc) {
+        printf("ERROR: initialization of libopc failed.\n");    
+        err=OPC_ERROR_STREAM;
+    } else {
+        printf("opc_dump FILENAME.\n\n");
+        printf("Sample: opc_dump test.docx\n");
+    }
+    time_t end_time=time(NULL);
+    fprintf(stderr, "time %.2lfsec\n", difftime(end_time, start_time));
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return (OPC_ERROR_NONE==err?0:3);	
+}
+

+ 94 - 0
sample/opc_part.c

@@ -0,0 +1,94 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Dump content of a part using either the binary or the XML interfaces.
+
+    Ussage:
+    opc_part FILENAME PARTNAME
+
+    Sample:
+    opc_part OOXMLI1.docx "word/document.xml"
+*/
+
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    opcInitLibrary();
+    opcContainer *c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_ONLY, NULL, NULL);
+    if (NULL!=c) {
+        opcPart part=opcPartFind(c, _X(argv[2]), NULL, 0);
+        if (OPC_PART_INVALID!=part) {
+            const xmlChar *type=opcPartGetType(c, part);
+            opc_uint32_t type_len=xmlStrlen(type);
+            opc_bool_t is_xml=NULL!=type && type_len>=3 && 'x'==type[type_len-3] && 'm'==type[type_len-2] && 'l'==type[type_len-1];
+            fprintf(stderr, "type=%s is_xml=%i\n", type, is_xml);
+            if (is_xml) {
+                mceTextReader_t reader;
+                if (OPC_ERROR_NONE==opcXmlReaderOpen(c, &reader, part, NULL, 0, 0)) {
+                    xmlTextWriter *writer=xmlNewTextWriterFile(NULL);
+                    xmlTextWriterSetIndent(writer, 1);
+                    if (NULL!=writer) {
+                        mceTextReaderDump(&reader, writer, 1);
+                    }
+                    xmlFreeTextWriter(writer);
+                    mceTextReaderCleanup(&reader);
+                }
+            } else  {
+                opcContainerInputStream *stream=opcContainerOpenInputStream(c, part);
+                if (NULL!=stream) {
+                    opc_uint32_t ret=0;
+                    opc_uint8_t buf[100];
+                    while((ret=opcContainerReadInputStream(stream, buf, sizeof(buf)))>0) {
+                        fwrite(buf, sizeof(opc_uint8_t), ret, stdout);
+                    }
+                    opcContainerCloseInputStream(stream);
+                }
+            }
+        }
+        opcContainerClose(c, OPC_CLOSE_NOW);
+    }
+    opcFreeLibrary();
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return 0;
+}
+

+ 110 - 0
sample/opc_proc.c

@@ -0,0 +1,110 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    time_t start_time=time(NULL);
+    opc_error_t err=OPC_ERROR_NONE;
+    if (OPC_ERROR_NONE==opcInitLibrary() && argc>1) {
+        opcContainer *c=NULL;
+        if (NULL!=(c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_WRITE, NULL, NULL))) {
+            pbool_t closed=PFALSE;
+            for(puint32_t i=2;i<argc;i++) {
+                if (xmlStrcmp(_X(argv[i]), _X("--dump"))==0) {
+                    opcContainerDump(c, stdout);
+                } else if (xmlStrcmp(_X(argv[i]), _X("--create"))==0 && i+4<argc) {
+                    const xmlChar *part_name=_X(argv[i+1]);
+                    const xmlChar *part_type=_X(argv[i+2]);
+                    const puint32_t part_flags=atoi(argv[i+3]);
+                    if (xmlStrcasecmp(part_type, _X("NULL"))==0) {
+                        part_type=NULL;
+                    }
+                    opcPart part=opcPartCreate(c, part_name, part_type, part_flags);
+                    if (OPC_PART_INVALID!=part) {
+                        opcContainerOutputStream* stream = opcContainerCreateOutputStream(c, part, OPC_COMPRESSIONOPTION_NORMAL);
+                        if (stream != NULL) {
+                            const char *filename=argv[i+4];
+                            FILE *in=fopen(filename, "rb");
+                            if (NULL!=in) {
+                                int ret=0;
+                                opc_uint8_t buf[100];
+                                while((ret=fread(buf, sizeof(opc_uint8_t), sizeof(buf), in))>0) {
+                                    opcContainerWriteOutputStream(stream, buf, ret);
+                                }
+                                fclose(in);
+                            }
+                            opcContainerCloseOutputStream(stream);
+                        }
+                    }
+                    i+=4;
+                } else if (xmlStrcmp(_X(argv[i]), _X("--delete"))==0 && i+1<argc) {
+                    const xmlChar *part_name=_X(argv[i+1]);
+                    OPC_ENSURE(OPC_ERROR_NONE==opcPartDelete(c, part_name)); 
+                    i+=1;
+                } else {
+                    printf("ERROR: unknown command \"%s\".\n", argv[i]);
+                    return 3;
+                }
+            }
+            if (!closed) {
+                opcContainerClose(c, OPC_CLOSE_NOW);
+            }
+        } else {
+            printf("ERROR: \"%s\" could not be opened.\n", argv[1]);
+            err=OPC_ERROR_STREAM;
+        }
+        opcFreeLibrary();
+    } else if (2==argc) {
+        printf("ERROR: initialization of libopc failed.\n");    
+        err=OPC_ERROR_STREAM;
+    } else {
+        printf("opc_proc FILENAME [COMMANDS].\n\n");
+        printf("Sample: opc_proc test.docx --dump\n");
+    }
+    time_t end_time=time(NULL);
+    fprintf(stderr, "time %.2lfsec\n", difftime(end_time, start_time));
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return (OPC_ERROR_NONE==err?0:3);	
+}
+

+ 122 - 0
sample/opc_properties.c

@@ -0,0 +1,122 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Dump core properties of an OPC container.
+
+    Ussage:
+    opc_properties FILENAME
+
+    Sample:
+    opc_properties OOXMLI1.docx
+*/
+
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+static void printValue(opcDCSimpleType_t *v) {
+    printf("\"%s\"", v->str);
+    if (NULL!=v->lang) 
+        printf("@%s", v->lang);
+}
+
+static void printPair(const char *name, opcDCSimpleType_t *value) {
+    printf("%s=", name);
+    printValue(value);
+    printf("\n");
+}
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+    time_t start_time=time(NULL);
+    opc_error_t err=OPC_ERROR_NONE;
+    if (OPC_ERROR_NONE==opcInitLibrary() && 2==argc) {
+        opcContainer *c=NULL;
+        if (NULL!=(c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_WRITE, NULL, NULL))) {
+            opcProperties_t cp;
+            opcCorePropertiesInit(&cp);
+            opcCorePropertiesRead(&cp, c);
+//            opcCorePropertiesSetString(&cp.category, _X("category"));
+//            opcCorePropertiesSetString(&cp.contentStatus, _X("contentStatus"));
+//            opcCorePropertiesSetString(&cp.created, _X("2011-04-13T06:24:00Z"));
+
+            if (NULL!=cp.category) printf("category=\"%s\"\n", cp.category);
+            if (NULL!=cp.contentStatus) printf("contentStatus=\"%s\"\n", cp.contentStatus);
+            if (NULL!=cp.created) printf("created=\"%s\"\n", cp.created);
+            if (NULL!=cp.creator.str) printPair("creator", &cp.creator);
+            if (NULL!=cp.description.str) printPair("description", &cp.description);
+            if (NULL!=cp.identifier.str) printPair("identifier", &cp.identifier);
+            if (cp.keyword_items>0) {
+                printf("keywords={");
+                for(opc_uint32_t i=0;i<cp.keyword_items;i++) {
+                    printValue(&cp.keyword_array[i]);
+                    if (i+1<cp.keyword_items) printf(", ");
+                }
+                printf("}\n");
+            }
+            if (NULL!=cp.language.str) printPair("language", &cp.language);
+            if (NULL!=cp.lastModifiedBy) printf("lastModifiedBy=\"%s\"\n", cp.lastModifiedBy);
+            if (NULL!=cp.lastPrinted) printf("lastPrinted=\"%s\"\n", cp.lastPrinted);
+            if (NULL!=cp.modified) printf("modified=\"%s\"\n", cp.modified);
+            if (NULL!=cp.revision) printf("revision=\"%s\"\n", cp.revision);
+            if (NULL!=cp.subject.str) printPair("subject", &cp.subject);
+            if (NULL!=cp.title.str) printPair("title", &cp.title);
+            if (NULL!=cp.version) printf("version=\"%s\"\n", cp.version);
+            opcCorePropertiesWrite(&cp, c);
+            opcCorePropertiesCleanup(&cp);
+            opcContainerClose(c, OPC_CLOSE_NOW);
+        } else {
+            printf("ERROR: \"%s\" could not be opened.\n", argv[1]);
+            err=OPC_ERROR_STREAM;
+        }
+        opcFreeLibrary();
+    } else if (2==argc) {
+        printf("ERROR: initialization of libopc failed.\n");    
+        err=OPC_ERROR_STREAM;
+    } else {
+        printf("opc_dump FILENAME.\n\n");
+        printf("Sample: opc_properties test.docx\n");
+    }
+    time_t end_time=time(NULL);
+    fprintf(stderr, "time %.2lfsec\n", difftime(end_time, start_time));
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return (OPC_ERROR_NONE==err?0:3);
+}
+

+ 110 - 0
sample/opc_relation.c

@@ -0,0 +1,110 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Traverse all relations of an OPC container or get the type of an relation.
+
+    Ussage:
+    * Traverse all relations:
+      opc_relation FILENAME
+    * Get type of root relation
+      opc_relation FILENAME RELATIONID
+    * Get type of part relation
+      opc_relation FILENAME PARTNAME RELATIONID
+
+    Sample:
+    opc_relation OOXMLI1.docx
+    opc_relation OOXMLI1.docx "rId1"
+    opc_relation OOXMLI1.docx "word/document.xml" "rId1"
+*/
+
+#include <opc/opc.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+static void traverse(opcContainer *c, opcPart source) {
+    for(opcRelation rel=opcRelationFirst(c, source);OPC_RELATION_INVALID!=rel;rel=opcRelationNext(c, source, rel)) {
+        opcPart target=opcRelationGetInternalTarget(c, source, rel);
+        if (OPC_PART_INVALID!=target) {
+            const xmlChar *prefix=NULL;
+            opc_uint32_t counter=-1;
+            const xmlChar *type=NULL;
+            opcRelationGetInformation(c, source, rel, &prefix, &counter, &type);
+            char buf[20]="";
+            if (-1!=counter) {
+                sprintf(buf, "%i", counter);
+            }
+            printf("%s %s%s %s %s\n", source, prefix, buf, target, type);
+            traverse(c, target);
+        }
+    }
+}
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+    opcInitLibrary();
+    opcContainer *c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_ONLY, NULL, NULL);
+    if (NULL!=c) {
+        if (3==argc) {
+            opcRelation rel=opcRelationFind(c, OPC_PART_INVALID, _X(argv[2]), NULL);
+            if (OPC_RELATION_INVALID!=rel) {
+                const xmlChar *type=NULL;
+                opcRelationGetInformation(c, OPC_PART_INVALID, rel, NULL, NULL, &type);
+                printf("type=%s\n", type);
+            }
+        } else if (4==argc) {
+            opcPart part=opcPartFind(c, _X(argv[2]), NULL, 0);
+            if (OPC_PART_INVALID!=part) {
+                opcRelation rel=opcRelationFind(c, part, _X(argv[3]), NULL);
+                if (OPC_RELATION_INVALID!=rel) {
+                    const xmlChar *type=NULL;
+                    opcRelationGetInformation(c, part, rel, NULL, NULL, &type);
+                    printf("type=%s\n", type);
+                }
+            }
+        } else {
+            traverse(c, OPC_PART_INVALID);
+        }
+        opcContainerClose(c, OPC_CLOSE_NOW);
+    }
+    opcFreeLibrary();
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return 0;
+}
+
+

+ 120 - 0
sample/opc_text.c

@@ -0,0 +1,120 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Extract all text of an Word document as HTML.
+
+    Ussage:
+    opc_text FILENAME
+
+    Sample:
+    opc_text OOXMLI1.docx
+*/
+
+
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+static void dumpText(mceTextReader_t *reader) {
+    mce_skip_attributes(reader);
+    mce_start_children(reader) {
+        mce_start_element(reader, _X("http://schemas.openxmlformats.org/wordprocessingml/2006/main"), _X("t")) {
+            mce_skip_attributes(reader);
+            mce_start_children(reader) {
+                mce_start_text(reader) {
+                    for(const xmlChar *txt=xmlTextReaderConstValue(reader->reader);0!=*txt;txt++) {
+                        switch(*txt) {
+                        case '<': 
+                            printf("&lt;");
+                            break;
+                        case '>': 
+                            printf("&gt;");
+                            break;
+                        case '&': 
+                            printf("&amp;");
+                            break;
+                        default:
+                            putc(*txt, stdout);
+                            break;
+                        }
+                    }
+                } mce_end_text(reader);
+            } mce_end_children(reader);
+        } mce_end_element(reader);
+        mce_start_element(reader, _X("http://schemas.openxmlformats.org/wordprocessingml/2006/main"), _X("p")) {
+            printf("<p>");
+            dumpText(reader);
+            printf("</p>\n");
+        } mce_end_element(reader);
+        mce_start_element(reader, NULL, NULL) {
+            dumpText(reader);
+        } mce_end_element(reader);
+    } mce_end_children(reader);
+}
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+    opcInitLibrary();
+    opcContainer *c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_ONLY, NULL, NULL);
+    if (NULL!=c) {
+        mceTextReader_t reader;
+        if (OPC_ERROR_NONE==opcXmlReaderOpen(c, &reader, _X("/word/document.xml"), NULL, 0, 0)) {
+            mce_start_document(&reader) {
+                mce_start_element(&reader, NULL, NULL) {
+                    printf("<html>\n");
+                    printf("<head>\n");
+                    printf("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n");
+                    printf("</head>\n");
+                    printf("<body>\n");
+                    dumpText(&reader);
+                    printf("<body>\n");
+                    printf("</html>\n");
+                } mce_end_element(&reader);
+            } mce_end_document(&reader);
+            mceTextReaderCleanup(&reader);
+        }
+        opcContainerClose(c, OPC_CLOSE_NOW);
+    }
+    opcFreeLibrary();
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return 0;
+}
+

+ 81 - 0
sample/opc_trim.c

@@ -0,0 +1,81 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Trim an OPC container, i.e. remove all unneeded bytes and make the container as small as possible.
+    [Content Types].xml and all _rels will be rewritten.
+
+    Ussage:
+    opc_trim FILENAME
+
+    Sample:
+    opc_trim OOXMLI1.docx
+*/
+#include <opc/opc.h>
+#include <stdio.h>
+#include <time.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+    time_t start_time=time(NULL);
+    opc_error_t err=OPC_ERROR_NONE;
+    if (OPC_ERROR_NONE==opcInitLibrary() && 2==argc) {
+        opcContainer *c=NULL;
+        if (NULL!=(c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_WRITE, NULL, NULL))) {
+            opcContainerDump(c, stdout);
+            opcContainerClose(c, OPC_CLOSE_TRIM);
+        } else {
+            printf("ERROR: \"%s\" could not be opened.\n", argv[1]);
+            err=OPC_ERROR_STREAM;
+        }
+        opcFreeLibrary();
+    } else if (2==argc) {
+        printf("ERROR: initialization of libopc failed.\n");    
+        err=OPC_ERROR_STREAM;
+    } else {
+        printf("opc_dump FILENAME.\n\n");
+        printf("Sample: opc_dump test.docx\n");
+    }
+    time_t end_time=time(NULL);
+    fprintf(stderr, "time %.2lfsec\n", difftime(end_time, start_time));
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return (OPC_ERROR_NONE==err?0:3);	
+}
+

+ 79 - 0
sample/opc_type.c

@@ -0,0 +1,79 @@
+/**
+ Copyright (c) 2010, Florian Reuter
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions 
+ are met:
+ 
+ * Redistributions of source code must retain the above copyright 
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the 
+ distribution.
+ * Neither the name of Florian Reuter nor the names of its contributors 
+ may be used to endorse or promote products derived from this 
+ software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED 
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+    Corretly get the type and an Office document.
+
+    Ussage:
+    opc_type FILENAME
+
+    Sample:
+    opc_type OOXMLI1.docx
+*/
+#include <opc/opc.h>
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
+int main( int argc, const char* argv[] )
+{
+#ifdef WIN32
+     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+    opcInitLibrary();
+    for(int i=1;i<argc;i++) {
+        opcContainer *c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_ONLY, NULL, NULL);
+        opcRelation rel=opcRelationFind(c, OPC_PART_INVALID, NULL, _X("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"));
+        if (OPC_RELATION_INVALID!=rel) {
+            opcPart mainPart=opcRelationGetInternalTarget(c, OPC_PART_INVALID, rel);
+            if (OPC_PART_INVALID!=mainPart) {
+                const xmlChar *type=opcPartGetType(c, mainPart);
+                printf("Office Document Type: %s\n", type);
+                if (0==xmlStrcmp(type, _X("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"))) {
+                    printf("WORD Document\n");
+                } else if (0==xmlStrcmp(type, _X("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"))) {
+                    printf("POWERPOINT Document\n");
+                } else if (0==xmlStrcmp(type, _X("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"))) {
+                    printf("EXCEL Document\n");
+                }
+            }
+        }
+        opcContainerClose(c, OPC_CLOSE_NOW);
+    }
+    opcFreeLibrary();
+#ifdef WIN32
+    OPC_ASSERT(!_CrtDumpMemoryLeaks());
+#endif
+    return 0;
+}
+
+

Some files were not shown because too many files changed in this diff