aboutsummaryrefslogtreecommitdiff
path: root/Mammoth/Couscous
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-04-30 17:20:53 +0100
committerMichael Williamson <mike@zwobble.org>2016-04-30 17:20:53 +0100
commitec5037c01868fecaec2eba89b975f3e53aded89a (patch)
treee0d5a092419bace577a90eb29699f5be57f36078 /Mammoth/Couscous
parent17d1a1f710edd8dfb92e75bcd273e04cee7c8146 (diff)
Export from java-mammoth 5f538798b147f0e76
Diffstat (limited to 'Mammoth/Couscous')
-rw-r--r--Mammoth/Couscous/Adapters.cs99
-rw-r--r--Mammoth/Couscous/HorribleHacks.cs34
-rw-r--r--Mammoth/Couscous/IterableExtensions.cs13
-rw-r--r--Mammoth/Couscous/JavaStringExtensions.cs33
-rw-r--r--Mammoth/Couscous/java/io/Closeable.cs8
-rw-r--r--Mammoth/Couscous/java/io/File.cs15
-rw-r--r--Mammoth/Couscous/java/io/IOException.cs17
-rw-r--r--Mammoth/Couscous/java/io/InputStream.cs5
-rw-r--r--Mammoth/Couscous/java/lang/IllegalArgumentException.cs8
-rw-r--r--Mammoth/Couscous/java/lang/IndexOutOfBoundsException.cs7
-rw-r--r--Mammoth/Couscous/java/lang/Iterable.cs5
-rw-r--r--Mammoth/Couscous/java/lang/RuntimeException.cs13
-rw-r--r--Mammoth/Couscous/java/lang/String.cs7
-rw-r--r--Mammoth/Couscous/java/lang/StringBuilder.cs14
-rw-r--r--Mammoth/Couscous/java/lang/UnsupportedOperationException.cs7
-rw-r--r--Mammoth/Couscous/java/math/BigInteger.cs24
-rw-r--r--Mammoth/Couscous/java/net/URI.cs42
-rw-r--r--Mammoth/Couscous/java/net/URISyntaxException.cs6
-rw-r--r--Mammoth/Couscous/java/net/URL.cs28
-rw-r--r--Mammoth/Couscous/java/nio/file/Path.cs16
-rw-r--r--Mammoth/Couscous/java/util/ArrayDeque.cs35
-rw-r--r--Mammoth/Couscous/java/util/ArrayList.cs49
-rw-r--r--Mammoth/Couscous/java/util/Arrays.cs7
-rw-r--r--Mammoth/Couscous/java/util/Collection.cs11
-rw-r--r--Mammoth/Couscous/java/util/Deque.cs10
-rw-r--r--Mammoth/Couscous/java/util/HashMap.cs69
-rw-r--r--Mammoth/Couscous/java/util/HashSet.cs34
-rw-r--r--Mammoth/Couscous/java/util/Iterator.cs6
-rw-r--r--Mammoth/Couscous/java/util/List.cs8
-rw-r--r--Mammoth/Couscous/java/util/Map.cs15
-rw-r--r--Mammoth/Couscous/java/util/NoSuchElementException.cs6
-rw-r--r--Mammoth/Couscous/java/util/Optional.cs103
-rw-r--r--Mammoth/Couscous/java/util/Set.cs6
-rw-r--r--Mammoth/Couscous/java/util/function/BiConsumer.cs5
-rw-r--r--Mammoth/Couscous/java/util/function/BiFunction.cs6
-rw-r--r--Mammoth/Couscous/java/util/function/BiPredicate.cs6
-rw-r--r--Mammoth/Couscous/java/util/function/Consumer.cs5
-rw-r--r--Mammoth/Couscous/java/util/function/Function.cs6
-rw-r--r--Mammoth/Couscous/java/util/function/Predicate.cs5
-rw-r--r--Mammoth/Couscous/java/util/function/Supplier.cs5
-rw-r--r--Mammoth/Couscous/mammoth/internal/docx/InMemoryDocxFile.cs13
-rw-r--r--Mammoth/Couscous/mammoth/internal/docx/ZippedDocxFile.cs30
-rw-r--r--Mammoth/Couscous/mammoth/internal/styles/parsing/LineParseException.cs15
-rw-r--r--Mammoth/Couscous/mammoth/internal/styles/parsing/ParseException.cs8
-rw-r--r--Mammoth/Couscous/mammoth/internal/styles/parsing/StyleMapParser.cs22
-rw-r--r--Mammoth/Couscous/mammoth/internal/util/Base64Encoding.cs18
-rw-r--r--Mammoth/Couscous/mammoth/internal/util/Casts.cs13
-rw-r--r--Mammoth/Couscous/mammoth/internal/util/Iterables.cs60
-rw-r--r--Mammoth/Couscous/mammoth/internal/util/Lists.cs97
-rw-r--r--Mammoth/Couscous/mammoth/internal/util/Maps.cs110
-rw-r--r--Mammoth/Couscous/mammoth/internal/util/PassThroughException.cs29
-rw-r--r--Mammoth/Couscous/mammoth/internal/util/Paths.cs8
-rw-r--r--Mammoth/Couscous/mammoth/internal/util/Sets.cs18
-rw-r--r--Mammoth/Couscous/mammoth/internal/util/Strings.cs18
-rw-r--r--Mammoth/Couscous/mammoth/internal/xml/parsing/SimpleSax.cs42
55 files changed, 1299 insertions, 0 deletions
diff --git a/Mammoth/Couscous/Adapters.cs b/Mammoth/Couscous/Adapters.cs
new file mode 100644
index 0000000..c45f35b
--- /dev/null
+++ b/Mammoth/Couscous/Adapters.cs
@@ -0,0 +1,99 @@
+using System.Collections.Generic;
+using System.Linq;
+using Mammoth.Couscous.java.lang;
+using Mammoth.Couscous.java.util;
+using Mammoth.Couscous.java.io;
+
+namespace Mammoth.Couscous {
+ internal static class FromJava {
+ internal static IEnumerable<T> IterableToEnumerable<T>(Iterable<T> iterable) {
+ Iterator<T> iterator = iterable.iterator();
+ while (iterator.hasNext()) {
+ yield return iterator.next();
+ }
+ }
+
+ internal static IDictionary<TKey, TValue> MapToDictionary<TKey, TValue>(Map<TKey, TValue> map) {
+ return map.AsDictionary();
+ }
+ }
+
+ internal static class ToJava {
+ internal static Iterable<T> EnumerableToIterable<T>(IEnumerable<T> enumerator) {
+ return new IterableWrapper<T>(enumerator);
+ }
+
+ private class IterableWrapper<T> : Iterable<T> {
+ private readonly IEnumerable<T> _enumerable;
+
+ internal IterableWrapper(IEnumerable<T> enumerable) {
+ _enumerable = enumerable;
+ }
+
+ public Iterator<T> iterator() {
+ return EnumeratorToIterator(_enumerable.GetEnumerator());
+ }
+ }
+
+ internal static Iterator<T> EnumeratorToIterator<T>(IEnumerator<T> enumerator) {
+ return new EnumeratorToIteratorAdapter<T>(enumerator);
+ }
+
+ private class EnumeratorToIteratorAdapter<T> : Iterator<T> {
+ private readonly IEnumerator<T> _enumerator;
+ private bool _ready;
+ private bool _hasNext;
+
+ internal EnumeratorToIteratorAdapter(IEnumerator<T> enumerator) {
+ _enumerator = enumerator;
+ _ready = false;
+ }
+
+ public bool hasNext() {
+ MakeReady();
+ return _hasNext;
+ }
+
+ public T next() {
+ MakeReady();
+ if (_hasNext) {
+ _ready = false;
+ return _enumerator.Current;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ private void MakeReady() {
+ if (!_ready) {
+ MoveNext();
+ }
+ }
+
+ private void MoveNext() {
+ _hasNext = _enumerator.MoveNext();
+ _ready = true;
+ }
+ }
+
+ internal static Map<TKey, TValue> DictionaryToMap<TKey, TValue>(IDictionary<TKey, TValue> dictionary) {
+ return new HashMap<TKey, TValue>(dictionary);
+ }
+
+ internal static java.util.List<T> ListToList<T>(IList<T> list) {
+ return new ArrayList<T>(list);
+ }
+
+ internal static java.io.InputStream StreamToInputStream(System.IO.Stream stream) {
+ return new StreamToInputStreamAdapter(stream);
+ }
+
+ private class StreamToInputStreamAdapter : InputStream {
+ public System.IO.Stream Stream { get; }
+
+ internal StreamToInputStreamAdapter(System.IO.Stream stream) {
+ Stream = stream;
+ }
+ }
+ }
+}
diff --git a/Mammoth/Couscous/HorribleHacks.cs b/Mammoth/Couscous/HorribleHacks.cs
new file mode 100644
index 0000000..c97dc0a
--- /dev/null
+++ b/Mammoth/Couscous/HorribleHacks.cs
@@ -0,0 +1,34 @@
+using Mammoth.Couscous.java.util;
+using Mammoth.Couscous.org.zwobble.mammoth.@internal.documents;
+using Mammoth.Couscous.org.zwobble.mammoth.@internal.styles.parsing;
+using System.Linq;
+
+namespace Mammoth.Couscous {
+ internal static class HorribleHacks {
+ internal static bool equals(this char first, int second) {
+ return first == second;
+ }
+
+ internal static bool equals(this Optional<string> first, Optional<string> second) {
+ return (!first.isPresent() && !second.isPresent()) || (first.isPresent() && second.isPresent() && first.get() == second.get());
+ }
+
+ internal static bool equals(this Map<string, string> firstMap, Map<string, string> secondMap) {
+ var first = FromJava.MapToDictionary(firstMap);
+ var second = FromJava.MapToDictionary(secondMap);
+ return first.Count == second.Count && first.All(item => second.ContainsKey(item.Key) && second[item.Key] == item.Value);
+ }
+
+ internal static bool equals(this NoteType first, NoteType second) {
+ return first == second;
+ }
+
+ internal static bool equals(this TokenType first, TokenType second) {
+ return first == second;
+ }
+
+ internal static string getMessage(this System.Exception exception) {
+ return exception.Message;
+ }
+ }
+}
diff --git a/Mammoth/Couscous/IterableExtensions.cs b/Mammoth/Couscous/IterableExtensions.cs
new file mode 100644
index 0000000..bac0b43
--- /dev/null
+++ b/Mammoth/Couscous/IterableExtensions.cs
@@ -0,0 +1,13 @@
+using Mammoth.Couscous.java.lang;
+using Mammoth.Couscous.java.util.function;
+
+namespace Mammoth.Couscous {
+ internal static class IterableExtensions {
+ public static void forEach<T>(this Iterable<T> iterable, Consumer<T> consumer) {
+ var iterator = iterable.iterator();
+ while (iterator.hasNext()) {
+ consumer.accept(iterator.next());
+ }
+ }
+ }
+}
diff --git a/Mammoth/Couscous/JavaStringExtensions.cs b/Mammoth/Couscous/JavaStringExtensions.cs
new file mode 100644
index 0000000..bf4e73f
--- /dev/null
+++ b/Mammoth/Couscous/JavaStringExtensions.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace Mammoth.Couscous {
+ internal static class JavaStringExtensions {
+ internal static char charAt(this string value, int index) {
+ return value[index];
+ }
+
+ internal static bool equalsIgnoreCase(this string first, string second) {
+ return first.Equals(second, StringComparison.InvariantCultureIgnoreCase);
+ }
+
+ internal static string replace(this string original, string search, string replacement) {
+ return original.Replace(search, replacement);
+ }
+
+ internal static bool isEmpty(this string value) {
+ return value.Length == 0;
+ }
+
+ internal static bool startsWith(this string value, string prefix) {
+ return value.StartsWith(prefix);
+ }
+
+ internal static string trim(this string value) {
+ return value.Trim();
+ }
+
+ internal static string[] split(this string value, string separator) {
+ return System.Text.RegularExpressions.Regex.Split(value, separator);
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/io/Closeable.cs b/Mammoth/Couscous/java/io/Closeable.cs
new file mode 100644
index 0000000..9dc10c5
--- /dev/null
+++ b/Mammoth/Couscous/java/io/Closeable.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace Mammoth.Couscous.java.io {
+ internal interface Closeable {
+ void close();
+ }
+}
+
diff --git a/Mammoth/Couscous/java/io/File.cs b/Mammoth/Couscous/java/io/File.cs
new file mode 100644
index 0000000..abff40a
--- /dev/null
+++ b/Mammoth/Couscous/java/io/File.cs
@@ -0,0 +1,15 @@
+using Mammoth.Couscous.java.nio.file;
+
+namespace Mammoth.Couscous.java.io {
+ internal class File {
+ internal string Path { get; }
+
+ internal File(string path) {
+ Path = path;
+ }
+
+ internal Path toPath() {
+ return new Path(Path);
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/io/IOException.cs b/Mammoth/Couscous/java/io/IOException.cs
new file mode 100644
index 0000000..f7b708e
--- /dev/null
+++ b/Mammoth/Couscous/java/io/IOException.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace Mammoth.Couscous.java.io
+{
+ internal class IOException : Exception {
+ internal IOException() : base() {
+ }
+
+ internal IOException(string message) : base(message) {
+ }
+
+ internal string getMessage() {
+ return Message;
+ }
+ }
+}
+
diff --git a/Mammoth/Couscous/java/io/InputStream.cs b/Mammoth/Couscous/java/io/InputStream.cs
new file mode 100644
index 0000000..b474bb8
--- /dev/null
+++ b/Mammoth/Couscous/java/io/InputStream.cs
@@ -0,0 +1,5 @@
+namespace Mammoth.Couscous.java.io {
+ internal interface InputStream {
+ System.IO.Stream Stream { get; }
+ }
+}
diff --git a/Mammoth/Couscous/java/lang/IllegalArgumentException.cs b/Mammoth/Couscous/java/lang/IllegalArgumentException.cs
new file mode 100644
index 0000000..57ef62b
--- /dev/null
+++ b/Mammoth/Couscous/java/lang/IllegalArgumentException.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace Mammoth.Couscous.java.lang {
+ internal class IllegalArgumentException : RuntimeException {
+ internal IllegalArgumentException(string message) : base(message) {
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/lang/IndexOutOfBoundsException.cs b/Mammoth/Couscous/java/lang/IndexOutOfBoundsException.cs
new file mode 100644
index 0000000..c56c7c1
--- /dev/null
+++ b/Mammoth/Couscous/java/lang/IndexOutOfBoundsException.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace Mammoth.Couscous.java.lang {
+ internal class IndexOutOfBoundsException : RuntimeException {
+ }
+}
+
diff --git a/Mammoth/Couscous/java/lang/Iterable.cs b/Mammoth/Couscous/java/lang/Iterable.cs
new file mode 100644
index 0000000..d050b06
--- /dev/null
+++ b/Mammoth/Couscous/java/lang/Iterable.cs
@@ -0,0 +1,5 @@
+namespace Mammoth.Couscous.java.lang {
+ internal interface Iterable<out T> {
+ java.util.Iterator<T> iterator();
+ }
+}
diff --git a/Mammoth/Couscous/java/lang/RuntimeException.cs b/Mammoth/Couscous/java/lang/RuntimeException.cs
new file mode 100644
index 0000000..cf882aa
--- /dev/null
+++ b/Mammoth/Couscous/java/lang/RuntimeException.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Mammoth.Couscous.java.lang
+{
+ internal class RuntimeException : Exception {
+ internal RuntimeException() : base() {
+ }
+
+ internal RuntimeException(string message) : base(message) {
+ }
+ }
+}
+
diff --git a/Mammoth/Couscous/java/lang/String.cs b/Mammoth/Couscous/java/lang/String.cs
new file mode 100644
index 0000000..bd0838d
--- /dev/null
+++ b/Mammoth/Couscous/java/lang/String.cs
@@ -0,0 +1,7 @@
+namespace Mammoth.Couscous.java.lang {
+ internal partial class String {
+ internal static string join(string separator, Iterable<string> values) {
+ return string.Join(separator, FromJava.IterableToEnumerable(values));
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/lang/StringBuilder.cs b/Mammoth/Couscous/java/lang/StringBuilder.cs
new file mode 100644
index 0000000..c894936
--- /dev/null
+++ b/Mammoth/Couscous/java/lang/StringBuilder.cs
@@ -0,0 +1,14 @@
+namespace Mammoth.Couscous.java.lang {
+ internal class StringBuilder {
+ private readonly System.Text.StringBuilder _builder = new System.Text.StringBuilder();
+
+ internal StringBuilder append(string value) {
+ _builder.Append(value);
+ return this;
+ }
+
+ internal string toString() {
+ return _builder.ToString();
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/lang/UnsupportedOperationException.cs b/Mammoth/Couscous/java/lang/UnsupportedOperationException.cs
new file mode 100644
index 0000000..da86874
--- /dev/null
+++ b/Mammoth/Couscous/java/lang/UnsupportedOperationException.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace Mammoth.Couscous.java.lang {
+ internal class UnsupportedOperationException : RuntimeException {
+ }
+}
+
diff --git a/Mammoth/Couscous/java/math/BigInteger.cs b/Mammoth/Couscous/java/math/BigInteger.cs
new file mode 100644
index 0000000..40ac3d3
--- /dev/null
+++ b/Mammoth/Couscous/java/math/BigInteger.cs
@@ -0,0 +1,24 @@
+namespace Mammoth.Couscous.java.math {
+ internal class BigInteger {
+ internal static readonly BigInteger _ONE = new BigInteger(1);
+
+ // TOOD: use proper BigInteger
+ private readonly long _value;
+
+ internal BigInteger(string value) {
+ _value = long.Parse(value);
+ }
+
+ internal BigInteger(long value) {
+ _value = value;
+ }
+
+ internal BigInteger subtract(BigInteger other) {
+ return new BigInteger(_value - other._value);
+ }
+
+ internal string toString() {
+ return _value.ToString();
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/net/URI.cs b/Mammoth/Couscous/java/net/URI.cs
new file mode 100644
index 0000000..818d694
--- /dev/null
+++ b/Mammoth/Couscous/java/net/URI.cs
@@ -0,0 +1,42 @@
+using System;
+
+namespace Mammoth.Couscous.java.net {
+ internal class URI {
+ private readonly Uri _uri;
+
+ internal URI(string uri) {
+ try {
+ _uri = new Uri(uri, UriKind.RelativeOrAbsolute);
+ } catch (UriFormatException exception) {
+ throw new URISyntaxException(exception.Message);
+ }
+ }
+
+ internal URI(Uri uri) {
+ _uri = uri;
+ }
+
+ internal bool isAbsolute() {
+ return _uri.IsAbsoluteUri;
+ }
+
+ internal URL toURL() {
+ return new URL(_uri.ToString());
+ }
+
+ internal URI resolve(string relativeUri) {
+ if (new URI(relativeUri).isAbsolute()) {
+ return new URI(relativeUri);
+ } else if (_uri.IsAbsoluteUri) {
+ return new URI(new Uri(_uri, relativeUri));
+ } else {
+ var path = _uri.ToString();
+ var lastSlashIndex = path.LastIndexOf("/");
+ var basePath = lastSlashIndex == -1
+ ? "."
+ : path.Substring(0, lastSlashIndex + 1);
+ return new URI(basePath + relativeUri);
+ }
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/net/URISyntaxException.cs b/Mammoth/Couscous/java/net/URISyntaxException.cs
new file mode 100644
index 0000000..7380ff6
--- /dev/null
+++ b/Mammoth/Couscous/java/net/URISyntaxException.cs
@@ -0,0 +1,6 @@
+namespace Mammoth.Couscous.java.net {
+ internal class URISyntaxException : System.Exception {
+ internal URISyntaxException(string message) : base(message) {
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/net/URL.cs b/Mammoth/Couscous/java/net/URL.cs
new file mode 100644
index 0000000..88479e8
--- /dev/null
+++ b/Mammoth/Couscous/java/net/URL.cs
@@ -0,0 +1,28 @@
+using System.Net;
+using Mammoth.Couscous.java.io;
+
+namespace Mammoth.Couscous.java.net {
+ internal class URL {
+ private readonly string _url;
+
+ internal URL(string url) {
+ _url = url;
+ }
+
+ internal InputStream openStream() {
+ try {
+ var response = WebRequest.Create(_url).GetResponse();
+ try {
+ return ToJava.StreamToInputStream(response.GetResponseStream());
+ } catch {
+ response.Close();
+ throw;
+ }
+ } catch (System.UriFormatException) {
+ return ToJava.StreamToInputStream(System.IO.File.OpenRead(_url));
+ } catch (System.Net.WebException exception) {
+ throw new java.io.IOException(exception.Message);
+ }
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/nio/file/Path.cs b/Mammoth/Couscous/java/nio/file/Path.cs
new file mode 100644
index 0000000..030f757
--- /dev/null
+++ b/Mammoth/Couscous/java/nio/file/Path.cs
@@ -0,0 +1,16 @@
+using Mammoth.Couscous.java.net;
+
+namespace Mammoth.Couscous.java.nio.file {
+ internal class Path {
+ private readonly string _path;
+
+ internal Path(string path) {
+ _path = path;
+ }
+
+ internal URI toUri() {
+ return new URI(_path);
+ }
+ }
+}
+
diff --git a/Mammoth/Couscous/java/util/ArrayDeque.cs b/Mammoth/Couscous/java/util/ArrayDeque.cs
new file mode 100644
index 0000000..df5447d
--- /dev/null
+++ b/Mammoth/Couscous/java/util/ArrayDeque.cs
@@ -0,0 +1,35 @@
+namespace Mammoth.Couscous.java.util {
+ internal class ArrayDeque<T> : Deque<T> {
+ private readonly System.Collections.Generic.IList<T> _list = new System.Collections.Generic.List<T>();
+
+ public int size() {
+ return _list.Count;
+ }
+
+ public T getFirst() {
+ if (_list.Count > 0) {
+ return _list[0];
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public T getLast() {
+ if (_list.Count > 0) {
+ return _list[_list.Count - 1];
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public void add(T value) {
+ _list.Add(value);
+ }
+
+ public T removeLast() {
+ T value = getLast();
+ _list.RemoveAt(_list.Count - 1);
+ return value;
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/util/ArrayList.cs b/Mammoth/Couscous/java/util/ArrayList.cs
new file mode 100644
index 0000000..4414123
--- /dev/null
+++ b/Mammoth/Couscous/java/util/ArrayList.cs
@@ -0,0 +1,49 @@
+using Mammoth.Couscous.java.lang;
+using Mammoth.Couscous.java.util;
+
+namespace Mammoth.Couscous.java.util {
+ internal class ArrayList<T> : List<T> {
+ private readonly System.Collections.Generic.IList<T> _list;
+
+ internal ArrayList() : this(new System.Collections.Generic.List<T>()) {
+ }
+
+ internal ArrayList(System.Collections.Generic.IList<T> list) {
+ _list = list;
+ }
+
+ public Iterator<T> iterator() {
+ return ToJava.EnumeratorToIterator(_list.GetEnumerator());
+ }
+
+ public bool isEmpty() {
+ return _list.Count == 0;
+ }
+
+ public int size() {
+ return _list.Count;
+ }
+
+ public bool contains(object value) {
+ return value is T && _list.Contains((T) value);
+ }
+
+ public T get(int index) {
+ if (index < 0 || index >= _list.Count) {
+ throw new IndexOutOfBoundsException();
+ } else {
+ return _list[index];
+ }
+ }
+
+ public void add(T value) {
+ _list.Add(value);
+ }
+
+ public T remove(int index) {
+ T value = _list[index];
+ _list.RemoveAt(index);
+ return value;
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/util/Arrays.cs b/Mammoth/Couscous/java/util/Arrays.cs
new file mode 100644
index 0000000..093db83
--- /dev/null
+++ b/Mammoth/Couscous/java/util/Arrays.cs
@@ -0,0 +1,7 @@
+namespace Mammoth.Couscous.java.util {
+ internal static class Arrays {
+ internal static List<T> asList<T>(T[] elements) {
+ return ToJava.ListToList(elements);
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/util/Collection.cs b/Mammoth/Couscous/java/util/Collection.cs
new file mode 100644
index 0000000..a0cae74
--- /dev/null
+++ b/Mammoth/Couscous/java/util/Collection.cs
@@ -0,0 +1,11 @@
+using Mammoth.Couscous.java.lang;
+
+namespace Mammoth.Couscous.java.util {
+ interface Collection<T> : Iterable<T> {
+ bool isEmpty();
+ int size();
+ bool contains(object value);
+
+ void add(T value);
+ }
+}
diff --git a/Mammoth/Couscous/java/util/Deque.cs b/Mammoth/Couscous/java/util/Deque.cs
new file mode 100644
index 0000000..c954fce
--- /dev/null
+++ b/Mammoth/Couscous/java/util/Deque.cs
@@ -0,0 +1,10 @@
+namespace Mammoth.Couscous.java.util {
+ internal interface Deque<T> {
+ int size();
+ T getFirst();
+ T getLast();
+
+ void add(T value);
+ T removeLast();
+ }
+}
diff --git a/Mammoth/Couscous/java/util/HashMap.cs b/Mammoth/Couscous/java/util/HashMap.cs
new file mode 100644
index 0000000..38e516e
--- /dev/null
+++ b/Mammoth/Couscous/java/util/HashMap.cs
@@ -0,0 +1,69 @@
+using System.Collections.Generic;
+using System.Linq;
+using Mammoth.Couscous.org.zwobble.mammoth.@internal.util;
+using Mammoth.Couscous.java.lang;
+
+namespace Mammoth.Couscous.java.util {
+ internal class HashMap<TKey, TValue> : Map<TKey, TValue> {
+ private readonly IDictionary<TKey, TValue> _dictionary;
+
+ internal HashMap() : this(new Dictionary<TKey, TValue>()) {
+ }
+
+ internal HashMap(IDictionary<TKey, TValue> dictionary) {
+ _dictionary = dictionary;
+ }
+
+ public void put(TKey key, TValue value) {
+ _dictionary[key] = value;
+ }
+
+ public bool containsKey(TKey key) {
+ return _dictionary.ContainsKey(key);
+ }
+
+ public Set<Map__Entry<TKey, TValue>> entrySet() {
+ return new EntrySet(_dictionary);
+ }
+
+ public Optional<TValue> _lookup(TKey key) {
+ if (_dictionary.ContainsKey(key)) {
+ return new Some<TValue>(_dictionary[key]);
+ } else {
+ return new None<TValue>();
+ }
+ }
+
+ public IDictionary<TKey, TValue> AsDictionary() {
+ return _dictionary;
+ }
+
+ internal class EntrySet : Set<Map__Entry<TKey, TValue>> {
+ private readonly IDictionary<TKey, TValue> _dictionary;
+
+ internal EntrySet(IDictionary<TKey, TValue> dictionary) {
+ _dictionary = dictionary;
+ }
+
+ public Iterator<Map__Entry<TKey, TValue>> iterator() {
+ return ToJava.EnumeratorToIterator(_dictionary.Select(entry => Maps.entry(entry.Key, entry.Value)).GetEnumerator());
+ }
+
+ public bool isEmpty() {
+ return _dictionary.Count == 0;
+ }
+
+ public int size() {
+ return _dictionary.Count;
+ }
+
+ public bool contains(object value) {
+ return value is TKey && _dictionary.ContainsKey((TKey) value);
+ }
+
+ public void add(Map__Entry<TKey, TValue> value) {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/util/HashSet.cs b/Mammoth/Couscous/java/util/HashSet.cs
new file mode 100644
index 0000000..ac10075
--- /dev/null
+++ b/Mammoth/Couscous/java/util/HashSet.cs
@@ -0,0 +1,34 @@
+using System.Collections.Generic;
+
+namespace Mammoth.Couscous.java.util {
+ internal class HashSet<T> : Set<T> {
+ private readonly ISet<T> _set;
+
+ internal HashSet() : this(new System.Collections.Generic.HashSet<T>()) {
+ }
+
+ internal HashSet(ISet<T> set) {
+ _set = set;
+ }
+
+ public Iterator<T> iterator() {
+ return ToJava.EnumeratorToIterator(_set.GetEnumerator());
+ }
+
+ public bool isEmpty() {
+ return _set.Count == 0;
+ }
+
+ public int size() {
+ return _set.Count;
+ }
+
+ public bool contains(object value) {
+ return value is T && _set.Contains((T)value);
+ }
+
+ public void add(T value) {
+ _set.Add(value);
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/util/Iterator.cs b/Mammoth/Couscous/java/util/Iterator.cs
new file mode 100644
index 0000000..0ae48b2
--- /dev/null
+++ b/Mammoth/Couscous/java/util/Iterator.cs
@@ -0,0 +1,6 @@
+namespace Mammoth.Couscous.java.util {
+ internal interface Iterator<out T> {
+ bool hasNext();
+ T next();
+ }
+}
diff --git a/Mammoth/Couscous/java/util/List.cs b/Mammoth/Couscous/java/util/List.cs
new file mode 100644
index 0000000..45a9299
--- /dev/null
+++ b/Mammoth/Couscous/java/util/List.cs
@@ -0,0 +1,8 @@
+using Mammoth.Couscous.java.lang;
+
+namespace Mammoth.Couscous.java.util {
+ interface List<T> : Collection<T> {
+ T get(int index);
+ T remove(int index);
+ }
+}
diff --git a/Mammoth/Couscous/java/util/Map.cs b/Mammoth/Couscous/java/util/Map.cs
new file mode 100644
index 0000000..5405c77
--- /dev/null
+++ b/Mammoth/Couscous/java/util/Map.cs
@@ -0,0 +1,15 @@
+namespace Mammoth.Couscous.java.util {
+ internal interface Map<K, V> {
+ void put(K key, V value);
+ bool containsKey(K key);
+ Set<Map__Entry<K, V>> entrySet();
+
+ Optional<V> _lookup(K key);
+ System.Collections.Generic.IDictionary<K, V> AsDictionary();
+ }
+
+ internal interface Map__Entry<K, V> {
+ K getKey();
+ V getValue();
+ }
+}
diff --git a/Mammoth/Couscous/java/util/NoSuchElementException.cs b/Mammoth/Couscous/java/util/NoSuchElementException.cs
new file mode 100644
index 0000000..4a1ee9c
--- /dev/null
+++ b/Mammoth/Couscous/java/util/NoSuchElementException.cs
@@ -0,0 +1,6 @@
+using Mammoth.Couscous.java.lang;
+
+namespace Mammoth.Couscous.java.util {
+ internal class NoSuchElementException : RuntimeException {
+ }
+}
diff --git a/Mammoth/Couscous/java/util/Optional.cs b/Mammoth/Couscous/java/util/Optional.cs
new file mode 100644
index 0000000..f295688
--- /dev/null
+++ b/Mammoth/Couscous/java/util/Optional.cs
@@ -0,0 +1,103 @@
+using System;
+using Mammoth.Couscous.java.util.function;
+
+namespace Mammoth.Couscous.java.util
+{
+ internal interface Optional<T>
+ {
+ bool isPresent();
+ Optional<U> map<U>(Function<T, U> function);
+ Optional<U> flatMap<U>(Function<T, Optional<U>> function);
+ T orElse(T value);
+ T orElseGet(Supplier<T> supplier);
+ T orElseThrow<TException>(Supplier<TException> exceptionSupplier) where TException : Exception;
+ T get();
+ void ifPresent(Consumer<T> consumer);
+ }
+
+ internal class None<T> : Optional<T> {
+ public bool isPresent() {
+ return false;
+ }
+
+ public Optional<U> map<U>(Function<T, U> function) {
+ return new None<U>();
+ }
+
+ public Optional<U> flatMap<U>(Function<T, Optional<U>> function) {
+ return new None<U>();
+ }
+
+ public T orElse(T value) {
+ return value;
+ }
+
+ public T orElseGet(Supplier<T> supplier) {
+ return supplier.get();
+ }
+
+ public T orElseThrow<TException>(Supplier<TException> exceptionSupplier) where TException : Exception {
+ throw exceptionSupplier.get();
+ }
+
+ public T get() {
+ throw new NoSuchElementException();
+ }
+
+ public void ifPresent(Consumer<T> consumer) {
+ }
+ }
+
+ internal class Some<T> : Optional<T> {
+ private readonly T _value;
+
+ internal Some(T value) {
+ _value = value;
+ }
+
+ public bool isPresent() {
+ return true;
+ }
+
+ public Optional<U> map<U>(Function<T, U> function) {
+ return new Some<U>(function.apply(_value));
+ }
+
+ public Optional<U> flatMap<U>(Function<T, Optional<U>> function) {
+ return function.apply(_value);
+ }
+
+ public T orElse(T value) {
+ return _value;
+ }
+
+ public T orElseGet(Supplier<T> supplier) {
+ return _value;
+ }
+
+ public T orElseThrow<TException>(Supplier<TException> exceptionSupplier) where TException : Exception {
+ return _value;
+ }
+
+ public T get() {
+ return _value;
+ }
+
+ public void ifPresent(Consumer<T> consumer) {
+ consumer.accept(_value);
+ }
+ }
+
+ internal static class Optional
+ {
+ internal static Optional<T> empty<T>()
+ {
+ return new None<T>();
+ }
+
+ internal static Optional<T> of<T>(T value)
+ {
+ return new Some<T> (value);
+ }
+ }
+}
diff --git a/Mammoth/Couscous/java/util/Set.cs b/Mammoth/Couscous/java/util/Set.cs
new file mode 100644
index 0000000..34a23ac
--- /dev/null
+++ b/Mammoth/Couscous/java/util/Set.cs
@@ -0,0 +1,6 @@
+using Mammoth.Couscous.java.lang;
+
+namespace Mammoth.Couscous.java.util {
+ internal interface Set<T> : Collection<T> {
+ }
+}
diff --git a/Mammoth/Couscous/java/util/function/BiConsumer.cs b/Mammoth/Couscous/java/util/function/BiConsumer.cs
new file mode 100644
index 0000000..9479a78
--- /dev/null
+++ b/Mammoth/Couscous/java/util/function/BiConsumer.cs
@@ -0,0 +1,5 @@
+namespace Mammoth.Couscous.java.util.function {
+ internal interface BiConsumer<T1, T2> {
+ void accept(T1 first, T2 second);
+ }
+}
diff --git a/Mammoth/Couscous/java/util/function/BiFunction.cs b/Mammoth/Couscous/java/util/function/BiFunction.cs
new file mode 100644
index 0000000..050f85f
--- /dev/null
+++ b/Mammoth/Couscous/java/util/function/BiFunction.cs
@@ -0,0 +1,6 @@
+namespace Mammoth.Couscous.java.util.function
+{
+ internal interface BiFunction<T1, T2, U> {
+ U apply(T1 first, T2 second);
+ }
+} \ No newline at end of file
diff --git a/Mammoth/Couscous/java/util/function/BiPredicate.cs b/Mammoth/Couscous/java/util/function/BiPredicate.cs
new file mode 100644
index 0000000..0419a6e
--- /dev/null
+++ b/Mammoth/Couscous/java/util/function/BiPredicate.cs
@@ -0,0 +1,6 @@
+namespace Mammoth.Couscous.java.util.function
+{
+ internal interface BiPredicate<T, U> {
+ bool test(T first, U second);
+ }
+} \ No newline at end of file
diff --git a/Mammoth/Couscous/java/util/function/Consumer.cs b/Mammoth/Couscous/java/util/function/Consumer.cs
new file mode 100644
index 0000000..f80d426
--- /dev/null
+++ b/Mammoth/Couscous/java/util/function/Consumer.cs
@@ -0,0 +1,5 @@
+namespace Mammoth.Couscous.java.util.function {
+ internal interface Consumer<T> {
+ void accept(T value);
+ }
+} \ No newline at end of file
diff --git a/Mammoth/Couscous/java/util/function/Function.cs b/Mammoth/Couscous/java/util/function/Function.cs
new file mode 100644
index 0000000..2b4d3ae
--- /dev/null
+++ b/Mammoth/Couscous/java/util/function/Function.cs
@@ -0,0 +1,6 @@
+namespace Mammoth.Couscous.java.util.function
+{
+ internal interface Function<T, U> {
+ U apply(T arg);
+ }
+} \ No newline at end of file
diff --git a/Mammoth/Couscous/java/util/function/Predicate.cs b/Mammoth/Couscous/java/util/function/Predicate.cs
new file mode 100644
index 0000000..2023309
--- /dev/null
+++ b/Mammoth/Couscous/java/util/function/Predicate.cs
@@ -0,0 +1,5 @@
+namespace Mammoth.Couscous.java.util.function {
+ internal interface Predicate<T> {
+ bool test(T value);
+ }
+} \ No newline at end of file
diff --git a/Mammoth/Couscous/java/util/function/Supplier.cs b/Mammoth/Couscous/java/util/function/Supplier.cs
new file mode 100644
index 0000000..eab3ffb
--- /dev/null
+++ b/Mammoth/Couscous/java/util/function/Supplier.cs
@@ -0,0 +1,5 @@
+namespace Mammoth.Couscous.java.util.function {
+ internal interface Supplier<T> {
+ T get();
+ }
+} \ No newline at end of file
diff --git a/Mammoth/Couscous/mammoth/internal/docx/InMemoryDocxFile.cs b/Mammoth/Couscous/mammoth/internal/docx/InMemoryDocxFile.cs
new file mode 100644
index 0000000..9b7efd0
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/docx/InMemoryDocxFile.cs
@@ -0,0 +1,13 @@
+using Mammoth.Couscous.java.io;
+using Mammoth.Couscous.java.util;
+using System.IO;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.docx {
+ internal class InMemoryDocxFile {
+ internal static DocxFile fromStream(InputStream stream) {
+ var memoryStream = new MemoryStream();
+ stream.Stream.CopyTo(memoryStream);
+ return new ZippedDocxFile(memoryStream);
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/docx/ZippedDocxFile.cs b/Mammoth/Couscous/mammoth/internal/docx/ZippedDocxFile.cs
new file mode 100644
index 0000000..cf39e63
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/docx/ZippedDocxFile.cs
@@ -0,0 +1,30 @@
+using System.IO.Compression;
+using Mammoth.Couscous.java.io;
+using Mammoth.Couscous.java.util;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.docx {
+ internal class ZippedDocxFile : DocxFile {
+ private readonly ZipArchive _zipFile;
+
+ internal ZippedDocxFile(File file) {
+ _zipFile = ZipFile.OpenRead(file.Path);
+ }
+
+ internal ZippedDocxFile(System.IO.Stream stream) {
+ _zipFile = new ZipArchive(stream);
+ }
+
+ public Optional<InputStream> tryGetInputStream(string name) {
+ var entry = _zipFile.GetEntry(name);
+ if (entry == null) {
+ return Optional.empty<InputStream>();
+ } else {
+ return Optional.of(ToJava.StreamToInputStream(entry.Open()));
+ }
+ }
+
+ public void close() {
+ _zipFile.Dispose();
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/styles/parsing/LineParseException.cs b/Mammoth/Couscous/mammoth/internal/styles/parsing/LineParseException.cs
new file mode 100644
index 0000000..6ca9381
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/styles/parsing/LineParseException.cs
@@ -0,0 +1,15 @@
+using Mammoth.Couscous.java.lang;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.styles.parsing {
+ internal class LineParseException : RuntimeException {
+ private readonly Token _token;
+
+ internal LineParseException(Token token, string message) : base(message) {
+ _token = token;
+ }
+
+ internal Token getToken() {
+ return _token;
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/styles/parsing/ParseException.cs b/Mammoth/Couscous/mammoth/internal/styles/parsing/ParseException.cs
new file mode 100644
index 0000000..73f349c
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/styles/parsing/ParseException.cs
@@ -0,0 +1,8 @@
+using Mammoth.Couscous.java.lang;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.styles.parsing {
+ internal class ParseException : RuntimeException {
+ internal ParseException(string message) : base(message) {
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/styles/parsing/StyleMapParser.cs b/Mammoth/Couscous/mammoth/internal/styles/parsing/StyleMapParser.cs
new file mode 100644
index 0000000..53315f3
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/styles/parsing/StyleMapParser.cs
@@ -0,0 +1,22 @@
+using Mammoth.Couscous.java.util;
+using Mammoth.Couscous.org.zwobble.mammoth.@internal.styles;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.styles.parsing {
+ internal static class StyleMapParser {
+ internal static StyleMap parseStyleMappings(List<string> mappings) {
+ return DefaultStyleMap();
+ }
+
+ internal static StyleMap parse(string styleMap) {
+ return DefaultStyleMap();
+ }
+
+ private static StyleMap DefaultStyleMap() {
+ return StyleMap.builder()
+
+ .mapParagraph(ParagraphMatcher.styleName("Normal"), HtmlPath.element("p"))
+
+ .build();
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/util/Base64Encoding.cs b/Mammoth/Couscous/mammoth/internal/util/Base64Encoding.cs
new file mode 100644
index 0000000..24d2f9c
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/util/Base64Encoding.cs
@@ -0,0 +1,18 @@
+using Mammoth.Couscous.java.lang;
+using Mammoth.Couscous.java.io;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util {
+ internal static class Base64Encoding {
+ internal static string streamToBase64(SupplierWithException<InputStream, IOException> streamSupplier) {
+ using (var stream = streamSupplier.get().Stream) {
+ return streamToBase64(stream);
+ }
+ }
+
+ internal static string streamToBase64(System.IO.Stream stream) {
+ var memoryStream = new System.IO.MemoryStream();
+ stream.CopyTo(memoryStream);
+ return System.Convert.ToBase64String(memoryStream.ToArray());
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/util/Casts.cs b/Mammoth/Couscous/mammoth/internal/util/Casts.cs
new file mode 100644
index 0000000..c342e20
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/util/Casts.cs
@@ -0,0 +1,13 @@
+using Mammoth.Couscous.java.util;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util {
+ internal static class Casts {
+ internal static Optional<T> tryCast<T>(System.Type type, object value) {
+ if (value is T) {
+ return new Some<T>((T) value);
+ } else {
+ return new None<T>();
+ }
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/util/Iterables.cs b/Mammoth/Couscous/mammoth/internal/util/Iterables.cs
new file mode 100644
index 0000000..b1e1477
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/util/Iterables.cs
@@ -0,0 +1,60 @@
+using System.Collections.Generic;
+using System.Linq;
+using Mammoth.Couscous.java.lang;
+using Mammoth.Couscous.java.util;
+using Mammoth.Couscous.java.util.function;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util
+{
+ internal static class Iterables
+ {
+ internal static T getFirst<T>(Iterable<T> iterable, T defaultValue) {
+ var iterator = iterable.iterator();
+ if (iterator.hasNext()) {
+ return iterator.next();
+ } else {
+ return defaultValue;
+ }
+ }
+
+ internal static Optional<T> tryFind<T>(Iterable<T> iterable, Predicate<T> predicate) {
+ var iterator = iterable.iterator();
+ while (iterator.hasNext()) {
+ T value = iterator.next();
+ if (predicate.test(value)) {
+ return new Some<T>(value);
+ }
+ }
+ return new None<T>();
+ }
+
+ internal static Iterable<T> lazyFilter<T>(Iterable<T> iterable, Predicate<T> predicate) {
+ var enumerable = FromJava.IterableToEnumerable(iterable).Where(predicate.test);
+ return ToJava.EnumerableToIterable(enumerable);
+ }
+
+ internal static Iterable<U> lazyFilter<T, U>(Iterable<T> iterable, System.Type type) {
+ var enumerable = FromJava.IterableToEnumerable(iterable).OfType<U>();
+ return ToJava.EnumerableToIterable(enumerable);
+ }
+
+ internal static Iterable<U> lazyMap<T, U>(Iterable<T> iterable, Function<T, U> function) {
+ var enumerable = FromJava.IterableToEnumerable(iterable)
+ .Select(function.apply);
+ return ToJava.EnumerableToIterable(enumerable);
+ }
+
+ internal static Iterable<U> lazyFlatMap<T, U>(Iterable<T> iterable, Function<T, Iterable<U>> function) {
+ var enumerable = FromJava.IterableToEnumerable(iterable)
+ .SelectMany(element => FromJava.IterableToEnumerable(function.apply(element)));
+ return ToJava.EnumerableToIterable(enumerable);
+ }
+
+ internal static Iterable<T> lazyConcat<T>(Iterable<T> first, Iterable<T> second) {
+ var enumerable = FromJava.IterableToEnumerable(first)
+ .Concat(FromJava.IterableToEnumerable(second));
+ return ToJava.EnumerableToIterable(enumerable);
+ }
+ }
+}
+
diff --git a/Mammoth/Couscous/mammoth/internal/util/Lists.cs b/Mammoth/Couscous/mammoth/internal/util/Lists.cs
new file mode 100644
index 0000000..b914a34
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/util/Lists.cs
@@ -0,0 +1,97 @@
+using Mammoth.Couscous.java.lang;
+using Mammoth.Couscous.java.util;
+using Mammoth.Couscous.java.util.function;
+using System.Linq;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util {
+ internal static class Lists {
+ internal static List<T> list<T>(params T[] values) {
+ return ToJava.ListToList(values);
+ }
+
+ internal static List<T> toList<T>(Iterable<T> iterable) {
+ return ToJava.ListToList(FromJava.IterableToEnumerable(iterable).ToList());
+ }
+
+ internal static List<U> eagerMap<T, U>(Iterable<T> iterable, Function<T, U> function) {
+ var result = FromJava.IterableToEnumerable(iterable)
+ .Select(function.apply)
+ .ToList();
+ return ToJava.ListToList(result);
+ }
+
+ internal static List<U> eagerFlatMap<T, U>(Iterable<T> iterable, Function<T, Iterable<U>> function) {
+ var result = FromJava.IterableToEnumerable(iterable)
+ .SelectMany(element => FromJava.IterableToEnumerable(function.apply(element)))
+ .ToList();
+ return ToJava.ListToList(result);
+ }
+
+ internal static List<T> cons<T>(T head, Iterable<T> tail) {
+ var result = new T[] { head }
+ .Concat(FromJava.IterableToEnumerable(tail))
+ .ToList();
+ return ToJava.ListToList(result);
+ }
+
+ internal static List<T> eagerConcat<T>(Iterable<T> first, Iterable<T> second) {
+ var result = FromJava.IterableToEnumerable(first)
+ .Concat(FromJava.IterableToEnumerable(second))
+ .ToList();
+ return ToJava.ListToList(result);
+ }
+
+ internal static List<T> orderedBy<T, R>(Iterable<T> iterable, Function<T, R> getKey) {
+ var result = FromJava.IterableToEnumerable(iterable)
+ .OrderBy(getKey.apply)
+ .ToList();
+ return ToJava.ListToList(result);
+ }
+
+ internal static Optional<T> tryGetLast<T>(List<T> list) {
+ if (list.isEmpty()) {
+ return new None<T>();
+ } else {
+ return new Some<T>(list.get(list.size() - 1));
+ }
+ }
+
+ internal static Iterable<T> reversed<T>(List<T> list) {
+ return new ReversedList<T>(list);
+ }
+
+ private class ReversedList<T> : Iterable<T> {
+ private readonly List<T> _list;
+
+ internal ReversedList(List<T> list) {
+ _list = list;
+ }
+
+ public Iterator<T> iterator() {
+ return new ReverseIterator<T>(_list);
+ }
+ }
+
+ private class ReverseIterator<T> : Iterator<T> {
+ private readonly List<T> _list;
+ private int _nextIndex;
+
+ internal ReverseIterator(List<T> list) {
+ _list = list;
+ _nextIndex = _list.size() - 1;
+ }
+
+ public bool hasNext() {
+ return _nextIndex >= 0;
+ }
+
+ public T next() {
+ if (hasNext()) {
+ return _list.get(_nextIndex--);
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/util/Maps.cs b/Mammoth/Couscous/mammoth/internal/util/Maps.cs
new file mode 100644
index 0000000..bee2dac
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/util/Maps.cs
@@ -0,0 +1,110 @@
+using System.Linq;
+using Mammoth.Couscous.java.util;
+using Mammoth.Couscous.java.lang;
+using Mammoth.Couscous.java.util.function;
+using Mammoth.Couscous;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util
+{
+ internal static class Maps
+ {
+ internal static Map<K, V> map<K, V>() {
+ return ToJava.DictionaryToMap(new System.Collections.Generic.Dictionary<K, V>());
+ }
+
+ internal static Map<K, V> map<K, V>(K key1, V value1) {
+ return ToJava.DictionaryToMap(new System.Collections.Generic.Dictionary<K, V> {
+ {key1, value1}
+ });
+ }
+
+ internal static Map<K, V> map<K, V>(K key1, V value1, K key2, V value2) {
+ return ToJava.DictionaryToMap(new System.Collections.Generic.Dictionary<K, V> {
+ {key1, value1},
+ {key2, value2}
+ });
+ }
+
+ internal static Map<K, V> toMap<T, K, V>(Iterable<T> iterable, Function<T, Map__Entry<K, V>> function) {
+ var dictionary = FromJava.IterableToEnumerable(iterable)
+ .Select(function.apply)
+ .ToDictionary(entry => entry.getKey(), entry => entry.getValue());
+ return ToJava.DictionaryToMap(dictionary);
+
+ }
+
+ internal static Map<K, T> toMapWithKey<T, K>(Iterable<T> iterable, Function<T, K> function) {
+ var dictionary = FromJava.IterableToEnumerable(iterable)
+ .ToDictionary(function.apply);
+ return ToJava.DictionaryToMap(dictionary);
+ }
+
+ internal static Map<K, java.util.List<T>> toMultiMapWithKey<T, K>(Iterable<T> iterable, Function<T, K> function) {
+ var dictionary = FromJava.IterableToEnumerable(iterable)
+ .GroupBy(value => function.apply(value))
+ .ToDictionary(
+ grouping => grouping.Key,
+ grouping => ToJava.ListToList(grouping.ToList()));
+ return ToJava.DictionaryToMap(dictionary);
+ }
+
+ internal static Optional<V> lookup<K, V>(Map<K, V> map, K key) {
+ return map._lookup(key);
+ }
+
+ internal static Map<K2, V> eagerMapKeys<K1, K2, V>(Map<K1, V> map, Function<K1, K2> function) {
+ var dictionary = FromJava.MapToDictionary(map)
+ .ToDictionary(
+ entry => function.apply(entry.Key),
+ entry => entry.Value);
+ return ToJava.DictionaryToMap(dictionary);
+ }
+
+ internal static Map<K, V2> eagerMapValues<K, V1, V2>(Map<K, V1> map, Function<V1, V2> function) {
+ var dictionary = FromJava.MapToDictionary(map)
+ .ToDictionary(
+ entry => entry.Key,
+ entry => function.apply(entry.Value));
+ return ToJava.DictionaryToMap(dictionary);
+ }
+
+ internal static Map__Entry<K, V> entry<K, V>(K key, V value) {
+ return new Entry<K, V>(key, value);
+ }
+
+ private class Entry<K, V> : Map__Entry<K, V> {
+ private readonly K _key;
+ private readonly V _value;
+
+ internal Entry(K key, V value) {
+ this._key = key;
+ this._value = value;
+ }
+
+ public K getKey() {
+ return _key;
+ }
+
+ public V getValue() {
+ return _value;
+ }
+ }
+
+ internal static Builder<K, V> builder<K, V>() {
+ return new Builder<K, V>();
+ }
+
+ internal class Builder<K, V> {
+ private readonly System.Collections.Generic.IDictionary<K, V> _values = new System.Collections.Generic.Dictionary<K, V>();
+
+ internal Builder<K, V> put(K key, V value) {
+ _values[key] = value;
+ return this;
+ }
+
+ internal Map<K, V> build() {
+ return ToJava.DictionaryToMap(_values);
+ }
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/util/PassThroughException.cs b/Mammoth/Couscous/mammoth/internal/util/PassThroughException.cs
new file mode 100644
index 0000000..88597e3
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/util/PassThroughException.cs
@@ -0,0 +1,29 @@
+using Mammoth.Couscous.java.lang;
+using Mammoth.Couscous.java.io;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util {
+ internal class PassThroughException : RuntimeException {
+ internal static T wrap<T>(SupplierWithException<T, IOException> supplier) {
+ try {
+ return supplier.get();
+ } catch (IOException exception) {
+ throw new PassThroughException(exception);
+ }
+ }
+
+ internal static T unwrap<T>(SupplierWithException<T, IOException> supplier) {
+ try {
+ return supplier.get();
+ } catch (PassThroughException exception) {
+ throw exception._exception;
+ }
+ }
+
+ private readonly IOException _exception;
+
+ internal PassThroughException(IOException exception) {
+ _exception = exception;
+ }
+ }
+}
+
diff --git a/Mammoth/Couscous/mammoth/internal/util/Paths.cs b/Mammoth/Couscous/mammoth/internal/util/Paths.cs
new file mode 100644
index 0000000..ca876eb
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/util/Paths.cs
@@ -0,0 +1,8 @@
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util {
+ internal static class Paths {
+ internal static string getExtension(string path) {
+ int dotIndex = path.LastIndexOf('.');
+ return dotIndex == -1 ? "" : path.Substring(dotIndex + 1);
+ }
+ }
+}
diff --git a/Mammoth/Couscous/mammoth/internal/util/Sets.cs b/Mammoth/Couscous/mammoth/internal/util/Sets.cs
new file mode 100644
index 0000000..bfce619
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/util/Sets.cs
@@ -0,0 +1,18 @@
+using Mammoth.Couscous.java.lang;
+using Mammoth.Couscous.java.util;
+using Mammoth.Couscous.java.nio.file;
+using System;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util
+{
+ internal static class Sets {
+ internal static Set<T> set<T>(T[] values) {
+ return new HashSet<T>(new System.Collections.Generic.HashSet<T>(values));
+ }
+
+ internal static Set<T> toSet<T>(Iterable<T> iterable) {
+ return new HashSet<T>(new System.Collections.Generic.HashSet<T>(FromJava.IterableToEnumerable(iterable)));
+ }
+ }
+}
+
diff --git a/Mammoth/Couscous/mammoth/internal/util/Strings.cs b/Mammoth/Couscous/mammoth/internal/util/Strings.cs
new file mode 100644
index 0000000..65f5e0b
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/util/Strings.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util {
+ internal static class Strings {
+ internal static string trimLeft(string value, int character) {
+ int index = 0;
+ while (index < value.Length && value[index] == character) {
+ index++;
+ }
+ return value.Substring(index);
+ }
+
+ internal static bool isNullOrEmpty(string value) {
+ return string.IsNullOrEmpty(value);
+ }
+ }
+}
+
diff --git a/Mammoth/Couscous/mammoth/internal/xml/parsing/SimpleSax.cs b/Mammoth/Couscous/mammoth/internal/xml/parsing/SimpleSax.cs
new file mode 100644
index 0000000..65f63c3
--- /dev/null
+++ b/Mammoth/Couscous/mammoth/internal/xml/parsing/SimpleSax.cs
@@ -0,0 +1,42 @@
+using Mammoth.Couscous.java.io;
+using Mammoth.Couscous.java.util;
+using System.Xml;
+
+namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.xml.parsing {
+ internal static class SimpleSax {
+ internal static void parseStream(InputStream input, SimpleSaxHandler handler) {
+ var reader = XmlReader.Create(input.Stream);
+ while (reader.Read()) {
+ switch (reader.NodeType) {
+ case XmlNodeType.Element:
+ var name = new ElementName(reader.NamespaceURI, reader.LocalName);
+ var attributes = new HashMap<ElementName, string>();
+ var isEmpty = reader.IsEmptyElement;
+ for (int attributeIndex = 0; attributeIndex < reader.AttributeCount; attributeIndex++) {
+ reader.MoveToAttribute(attributeIndex);
+ attributes.put(new ElementName(reader.NamespaceURI, reader.LocalName), reader.Value);
+ }
+ handler.startElement(name, attributes);
+ if (isEmpty) {
+ handler.endElement();
+ }
+ break;
+ case XmlNodeType.CDATA:
+ case XmlNodeType.Text:
+ case XmlNodeType.SignificantWhitespace:
+ handler.characters(reader.Value);
+ break;
+ case XmlNodeType.EntityReference:
+ throw new System.NotImplementedException();
+ case XmlNodeType.EndElement:
+ handler.endElement();
+ break;
+ }
+ }
+ }
+
+ internal static void parseString(string value, SimpleSaxHandler handler) {
+ throw new System.NotImplementedException();
+ }
+ }
+}