text:
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Collections;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Runtime.CompilerServices;

using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

using PHP.Core;
using System.Diagnostics;
#if SILVERLIGHT
using PHP.CoreCLR;
#endif

namespace PHP.Library
{
	#region Enums (FileOptions, WriteContentsOptions, ...)

	///
	/// Options used in the <c>flags</c> argument of the 'fopen' function.
	///
	[Flags]
	public enum FileOpenOptions
	{
		/// Default option for the <c>flags</c> argument.
		Empty = 0,
		/// Search for the file in the <c>include_path</c> too (1).
		[ImplementsConstant("FILE_USE_INCLUDE_PATH")]
		UseIncludePath = 0x1

		// UNUSED    /// Do not create a default context if none is provided (16).
		// UNUSED    [ImplementsConstant("FILE_NO_DEFAULT_CONTEXT")] NoDefaultContext = 0x10
	}

	///
	/// Options used in the <c>flags</c> argument of PHP Filesystem functions.
	///
	[Flags]
	public enum FileOptions
	{
		///
		/// Default.
		///
		Empty = 0,

		///
		/// Search for the file in the <c>include_path</c> too (1).
		///
		UseIncludePath = FileOpenOptions.UseIncludePath,

		///
		/// Do not include the line break characters to the result in <c>file()</c> (2).
		///
		[ImplementsConstant("FILE_IGNORE_NEW_LINES")]
		TrimLineEndings = 2,

		///
		/// Do not include empty lines to the resulting <see cref="PhpArray"/> in <c>file()</c> (4).
		///
		[ImplementsConstant("FILE_SKIP_EMPTY_LINES")]
		SkipEmptyLines = 4
	}

	///
	/// The options used as the <c>flag</c> argument of <see cref="PhpFile.WriteContents"/>.
	///
	[Flags]
	public enum WriteContentsOptions
	{
		///
		/// Empty option (default).
		///
		Empty = 0,

		///
		/// Search for the file in the <c>include_path</c> too (1).
		///
		UseIncludePath = FileOptions.UseIncludePath,

		///
		/// Append the given data at the end of the file in <c>file_put_contents</c> (8).
		///
		[ImplementsConstant("FILE_APPEND")]
		AppendContents = 8,

		///
		/// Acquire an exclusive lock on the file.
		///
		LockExclusive = StreamLockOptions.Exclusive
	}

	///
	/// The flags indicating which fields the <see cref="PhpPath.GetInfo"/>
	/// method should fill in the result array.
	///
	[Flags]
	public enum PathInfoOptions
	{
		///
		/// Fill the "dirname" field in results.
		///
		[ImplementsConstant("PATHINFO_DIRNAME")]
		DirName = 1,

		///
		/// Fill the "basename" field in results.
		///
		[ImplementsConstant("PATHINFO_BASENAME")]
		BaseName = 2,

		///
		/// Fill the "extension" field in results.
		///
		[ImplementsConstant("PATHINFO_EXTENSION")]
		Extension = 4,

		///
		/// Fill the "filename" field in results. Since PHP 5.2.0.
		///
        [ImplementsConstant("PATHINFO_FILENAME")]
		FileName = 8,

		///
		/// All the four options result in an array returned by <see cref="PhpPath.GetInfo"/>.
		///
		All = DirName | BaseName | Extension | FileName
	}

	#endregion

	///
	/// Provides PHP I/O operations using the set of StreamWrappers.
	///
	/// <threadsafety static="true"/>
	public static partial class PhpFile
	{
        ///
        /// Name of variable that is filled with response headers in case of file_get_contents and http protocol.
        ///
        internal const string HttpResponseHeaderName = "http_response_header";

		#region Constructors

		///
		/// Registers the ClassLibrary filters for the Core streams API.
		///
		static PhpFile()
		{
#if !SILVERLIGHT
            RequestContext.RequestEnd += new Action(StaticInfo.Clear);
#endif
			PhpFilter.AddSystemFilter(new StringFilterFactory());
			PhpFilter.AddSystemFilter(new EncodingFilterFactory());
			PhpFilter.AddSystemFilter(new DecodingFilterFactory());
		}

		#endregion

		#region make_absolute (Silverlight utility)
#if SILVERLIGHT

		[ImplementsFunction("sl_mkabsolute")]
		public static string MakeAbsoluteUrl(string relative)
		{
			return HttpPathUtils.Combine(System.Windows.Browser.HtmlPage.Document.DocumentUri.AbsoluteUri, "../" + relative);
		}

#endif
		#endregion

        #region fopen, tmpfile, fclose, feof, fflush

        ///
		/// Opens filename or URL using a registered StreamWrapper.
		///
		/// <param name="path">The file to be opened. The schema part of the URL specifies the wrapper to be used.</param>
		/// <param name="mode">The read/write and text/binary file open mode.</param>
		/// <returns>The file resource or false in case of failure.</returns>
		[ImplementsFunction("fopen")]
		[return: CastToFalse]
		public static PhpResource Open(string path, string mode)
		{
			return Open(path, mode, FileOpenOptions.Empty, StreamContext.Default);
		}

		///
		/// Opens filename or URL using a registered StreamWrapper.
		///
		/// <param name="path">The file to be opened. The schema part of the URL specifies the wrapper to be used.</param>
		/// <param name="mode">The read/write and text/binary file open mode.</param>
		/// <param name="flags">If set to true, then the include path is searched for relative filenames too.</param>
		/// <returns>The file resource or false in case of failure.</returns>
		[ImplementsFunction("fopen")]
		[return: CastToFalse]
		public static PhpResource Open(string path, string mode, FileOpenOptions flags)
		{
			return Open(path, mode, flags, StreamContext.Default);
		}

		///
		/// Opens filename or URL using a registered StreamWrapper.
		///
		/// <param name="path">The file to be opened. The schema part of the URL specifies the wrapper to be used.</param>
		/// <param name="mode">The read/write and text/binary file open mode.</param>
		/// <param name="flags">If set to true, then the include path is searched for relative filenames too.</param>
		/// <param name="context">A script context to be provided to the StreamWrapper.</param>
		/// <returns>The file resource or false in case of failure.</returns>
		[ImplementsFunction("fopen")]
		[return: CastToFalse]
		public static PhpResource Open(string path, string mode, FileOpenOptions flags, PhpResource context)
		{
			StreamContext sc = StreamContext.GetValid(context);
			if (sc == null) return null;

			if (String.IsNullOrEmpty(path))
			{
				PhpException.Throw(PhpError.Warning, LibResources.GetString("arg:empty", "path"));
				return null;
			}

			if (String.IsNullOrEmpty(mode))
			{
				PhpException.Throw(PhpError.Warning, LibResources.GetString("arg:empty", "mode"));
				return null;
			}

			return PhpStream.Open(path, mode, ProcessOptions(flags), sc);
		}

		///
		/// Prevents invalid options from the the options argument for StreamWrapper.Open().
		///
		/// <param name="flags">Flags passed to stream opening functions.</param>
		/// <returns>The StreamOpenFlags combination for the given arguments.</returns>
		internal static StreamOpenOptions ProcessOptions(FileOpenOptions flags)
		{
			StreamOpenOptions options = 0;

			if ((flags & FileOpenOptions.UseIncludePath) > 0)
				options |= StreamOpenOptions.UseIncludePath;

			if (!ScriptContext.CurrentContext.ErrorReportingDisabled)
				options |= StreamOpenOptions.ReportErrors;

			return options;
		}

		///
		/// Creates a temporary file.
		///
		/// <remarks>
		/// Creates a temporary file with an unique name in write mode,
		/// returning a file handle similar to the one returned by fopen().
		/// The file is automatically removed when closed (using fclose()),
		/// or when the script ends.
		/// </remarks>
		/// <returns></returns>
		[ImplementsFunction("tmpfile")]
		public static PhpResource OpenTemporary()
		{
			string path = PhpPath.GetTemporaryFilename(string.Empty, "php");

			StreamWrapper wrapper;
			if (!PhpStream.ResolvePath(ref path, out wrapper, CheckAccessMode.FileMayExist, CheckAccessOptions.Empty))
				return null;

			return wrapper.Open(ref path, "w+b", StreamOpenOptions.Temporary, StreamContext.Default);
		}

        ///
		/// Close an open file pointer.
		///
		/// <param name="handle">A PhpResource passed to the PHP function.</param>
		/// <returns>True if successful.</returns>
		[ImplementsFunction("fclose")]
		public static bool Close(PhpResource handle)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return false;
			if (stream.IsPersistent)
			{
				// Do not close persisten streams (incl. for example STDOUT).
				stream.Flush();
				return true;
			}
			stream.Close();
			return true;
		}

		///
		/// Tests for end-of-file on a file pointer.
		///
		/// <param name="handle">A PhpResource passed to the PHP function.</param>
		/// <returns>True if successful.</returns>
		[ImplementsFunction("feof")]
		public static bool Eof(PhpResource handle)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return false;
			return stream.Eof;
		}

		///
		/// Flushes the output to a file.
		///
		/// <param name="handle">A PhpResource passed to the PHP function.</param>
		/// <returns>True if successful.</returns>
		[ImplementsFunction("fflush")]
		public static bool Flush(PhpResource handle)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return false;
			return stream.Flush();
		}

		#endregion

		#region fprintf, fscanf

		///
		/// Writes the string formatted using <c>sprintf</c> to the given stream.
		///
		/// <param name="handle">A stream opened for writing.</param>
		/// <param name="format">The format string. For details, see PHP manual.</param>
		/// <param name="arguments">The arguments.
		/// See PHP manual for details.
		/// Besides, a type specifier "%C" is applicable. It converts an integer value to Unicode character.</param>
		/// <returns>Number of characters written of <c>false</c> in case of an error.</returns>
		[ImplementsFunction("fprintf")]
		[return: CastToFalse]
		public static int WriteFormatted(PhpResource handle, string format, params object[] arguments)
		{
			string formatted = PhpStrings.Format(format, arguments);
			if (formatted == String.Empty) return 0;
			return WriteInternal(handle, formatted, -1);
		}

		///
		/// Parses input from a file according to a format.
		///
		/// <param name="handle"></param>
		/// <param name="format"></param>
		/// <returns>A <see cref="PhpArray"/> containing the parsed values.</returns>
		[ImplementsFunction("fscanf")]
		[return: CastToFalse]
		public static PhpArray ReadLineFormat(PhpResource handle, string format)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return null;
			string line = stream.ReadLine(-1, null);
			return PhpStrings.ScanFormat(line, format);
		}

		///
		/// Parses input from a file according to a format.
		///
		/// <param name="handle"></param>
		/// <param name="format"></param>
		/// <param name="arg"></param>
		/// <param name="arguments"></param>
		/// <returns>The number of assigned values.</returns>
		[ImplementsFunction("fscanf")]
		[return: CastToFalse]
		public static int ReadLineFormat(PhpResource handle, string format, PhpReference arg, params PhpReference[] arguments)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return -1;
			string line = stream.ReadLine(-1, null);
			return PhpStrings.ScanFormat(line, format, arg, arguments);
		}

		#endregion

        #region fgetcsv, fputcsv, str_getcsv

        private const char DefaultCsvDelimiter = ',';
		private const char DefaultCsvEnclosure = '"';
        private const char DefaultCsvEscape = '\\';

        [ImplementsFunction("str_getcsv")]
        public static PhpArray ReadStrLineCsv( string input  )
        {
            return ReadStrLineCsv(input, DefaultCsvDelimiter, DefaultCsvEnclosure, DefaultCsvEscape);
        }
        [ImplementsFunction("str_getcsv")]
        public static PhpArray ReadStrLineCsv(string input, char delimiter)
        {
            return ReadStrLineCsv(input, delimiter, DefaultCsvEnclosure, DefaultCsvEscape);
        }
        [ImplementsFunction("str_getcsv")]
        public static PhpArray ReadStrLineCsv(string input, char delimiter, char enclosure)
        {
            return ReadStrLineCsv(input, delimiter, enclosure, DefaultCsvEscape);
        }
        [ImplementsFunction("str_getcsv")]
        public static PhpArray ReadStrLineCsv(string input, char delimiter, char enclosure, char escape)
        {
            bool firstLine = true;
            return ReadLineCsv(delegate()
            {
                if (!firstLine)
                    return null;

                firstLine = false;
                return input;
            },
            delimiter, enclosure, escape);
        }

		[ImplementsFunction("fgetcsv")]
        public static object ReadLineCsv(PhpResource handle)
		{
			return ReadLineCsv(handle, 0, DefaultCsvDelimiter, DefaultCsvEnclosure, DefaultCsvEscape);
		}

		[ImplementsFunction("fgetcsv")]
        public static object ReadLineCsv(PhpResource handle, int length)
		{
            return ReadLineCsv(handle, length, DefaultCsvDelimiter, DefaultCsvEnclosure, DefaultCsvEscape);
		}

        [ImplementsFunction("fgetcsv")]
        public static object ReadLineCsv(PhpResource handle, int length, char delimiter)
        {
            return ReadLineCsv(handle, length, delimiter, DefaultCsvEnclosure, DefaultCsvEscape);
        }

        [ImplementsFunction("fgetcsv")]
        public static object ReadLineCsv(PhpResource handle, int length, char delimiter, char enclosure)
        {
            return ReadLineCsv(handle, length, delimiter, enclosure, DefaultCsvEscape);
        }

        ///
        ///
        ///
        /// <param name="handle"></param>
        /// <param name="length"></param>
        /// <param name="delimiter"></param>
        /// <param name="enclosure"></param>
        /// <param name="escape_char">The escape character used in the CSV string.</param>
        /// <returns>Returns an indexed array containing the fields read.
        /// fgetcsv() returns NULL if an invalid handle is supplied or FALSE on other errors, including end of file.</returns>
		[ImplementsFunction("fgetcsv")]
		public static object ReadLineCsv(PhpResource handle, int length, char delimiter/*=','*/, char enclosure/*='"'*/, char escape_char /*= '\\'*/ )
		{
            // check arguments
			PhpStream stream = PhpStream.GetValid(handle, FileAccess.Read);
            if (stream == null) return null;
			if (length < 0) PhpException.InvalidArgument("length", LibResources.GetString("arg:negative"));
            if (length <= 0) length = -1;    // no length limit
            if (stream.Eof) return false;

            return ReadLineCsv(() => (stream.Eof ? null : stream.ReadLine(length, null)), delimiter, enclosure, escape_char);
		}

        ///
        /// CSV data line reader.
        /// In case of stream, it returns stream.GetLine() or null in case of EOF.
        /// In case of string input, it returns string for the first time, then null.
        /// ...
        ///
        /// <returns>Next line of CSV data or NULL in case of EOF.</returns>
        private delegate string CsvLineReader();

        private static PhpArray ReadLineCsv( CsvLineReader reader, char delimiter/*=','*/, char enclosure/*='"'*/, char escape_char /*= '\\'*/ )
        {
            // collect results
            PhpArray result = new PhpArray();

            int i = 0;  // index of currently scanned char
            string line = reader(); // currently scanned string
            bool eof = false;

            if (line == null)
            {
                result.Add(null);
                return result;
            }

            for (; ; )
            {
                Debug.Assert(i - 1 < line.Length);
                bool previous_field_delimited = (i == 0 || line[i - 1] == delimiter);

                // skip initial whitespace:
                while (i < line.Length && Char.IsWhiteSpace(line[i]) && line[i] != delimiter)
                    ++i;

                if (i >= line.Length)
                {
                    if (result.Count == 0)
                        result.Add(null);
                    else if (previous_field_delimited)
                        result.Add(string.Empty);

                    break;
                }
                else if (line[i] == delimiter)
                {
                    if (previous_field_delimited)
                        result.Add(string.Empty);
                    ++i;
                }
                else if (line[i] == enclosure)
                {
                    // enclosed string follows:
                    int start = ++i;
                    StringBuilder field_builder = new StringBuilder();

                    for (; ; )
                    {
                        // read until enclosure character found:
                        while (i < line.Length && line[i] != enclosure)
                        {
                            if (i + 1 < line.Length && line[i] == escape_char)
                                ++i;// skip escape char

                            ++i;    // skip following char
                        }

                        // end of line:
                        if (i == line.Length)
                        {
                            // append including eoln:
                            field_builder.Append(line, start, line.Length - start);

                            // field continues on the next line:
                            string nextLine = reader();
                            if (nextLine == null)
                            {
                                eof = true;
                                break;
                            }

                            line = nextLine;
                            start = i = 0;
                        }
                        else
                        {
                            Debug.Assert(line[i] == enclosure);
                            i++;

                            if (i < line.Length && line[i] == enclosure)
                            {
                                // escaped enclosure; add previous text including enclosure:
                                field_builder.Append(line, start, i - start);
                                start = ++i;
                            }
                            else
                            {
                                // end of enclosure:
                                field_builder.Append(line, start, i - 1 - start);
                                start = i;
                                break;
                            }
                        }
                    }

                    if (!eof)//if (!stream.Eof)
                    {
                        Debug.Assert(start == i && line.Length > 0);

                        int end = GetCsvDisclosedTextEnd(line, delimiter, ref i, escape_char);

                        field_builder.Append(line, start, end - start);
                    }

                    //result.Add(Core.Convert.Quote(field_builder.ToString(), context));
                    //result.Add(StringUtils.EscapeStringCustom(field_builder.ToString(), charsToEscape, escape));
                    result.Add(field_builder.ToString());
                }
                else
                {
                    // disclosed text:

                    int start = i;
                    int end = GetCsvDisclosedTextEnd(line, delimiter, ref i, escape_char);

                    //result.Add( Core.Convert.Quote(line.Substring(start, end - start), context));
                    //result.Add(StringUtils.EscapeStringCustom(line.Substring(start, end - start), charsToEscape, escape));
                    result.Add(line.Substring(start, end - start));
                }
            }

            return result;
        }
        private static int GetCsvDisclosedTextEnd(string line, char delimiter, ref int i, char escape_char)
		{
			// disclosed text follows enclosed one:
            while (i < line.Length && line[i] != delimiter)
            {
                i++;
            }

			// field ended by eoln or delimiter:
			if (i == line.Length)
			{
				// do not add eoln to the field:
                int dec = 0;
                if (line[i - 1] == '\n')
                {
                    dec++;
                    if (i > 1 && line[i - 2] == '\r')
                        dec++;
                }
                return i - dec;
			}
			else
			{
				Debug.Assert(line[i] == delimiter);

				// skip delimiter:
				return i++;
			}
		}

		[ImplementsFunction("fputcsv")]
		public static int WriteLineCsv(PhpResource handle, PhpArray fields)
		{
			return WriteLineCsv(handle, fields, DefaultCsvDelimiter, DefaultCsvEnclosure);
		}

		[ImplementsFunction("fputcsv")]
		public static int WriteLineCsv(PhpResource handle, PhpArray fields, char delimiter)
		{
			return WriteLineCsv(handle, fields, delimiter, DefaultCsvEnclosure);
		}

		/// <remarks>
		/// Affected by run-time quoting (data are unqouted before written)
		/// (<see cref="LocalConfiguration.VariablesSection.QuoteRuntimeVariables"/>).
		/// </remarks>
		[ImplementsFunction("fputcsv")]
		public static int WriteLineCsv(PhpResource handle, PhpArray fields, char delimiter, char enclosure)
		{
			PhpStream stream = PhpStream.GetValid(handle, FileAccess.Write);
			if (stream == null || !stream.CanWrite) return -1;

			ScriptContext context = ScriptContext.CurrentContext;
			char[] special_chars = { delimiter, ' ', '\\', '\t', '\r', '\n' };
			string str_enclosure = enclosure.ToString();
			string str_delimiter = delimiter.ToString();

			int initial_position = stream.WritePosition;
			foreach (object field in fields.Values)
			{
				string str_field = Core.Convert.Unquote(Core.Convert.ObjectToString(field), context);

				if (stream.WritePosition > initial_position)
					stream.WriteString(str_delimiter);

				int special_char_index = str_field.IndexOfAny(special_chars);
				int enclosure_index = str_field.IndexOf(enclosure);

				if (special_char_index >= 0 || enclosure_index >= 0)
				{
					stream.WriteString(str_enclosure);

					if (enclosure_index >= 0)
					{
						// escapes enclosure characters:
						int start = 0;
						for (; ; )
						{
							// writes string starting after the last enclosure and ending by the next one:
							stream.WriteString(str_field.Substring(start, enclosure_index - start + 1));
							stream.WriteString(str_enclosure);

							start = enclosure_index + 1;
							if (start >= str_field.Length) break;

							enclosure_index = str_field.IndexOf(enclosure, start);
							if (enclosure_index < 0)
							{
								// remaining substring:
								stream.WriteString(str_field.Substring(start));
								break;
							}
						}
					}
					else
					{
						stream.WriteString(str_field);
					}

					stream.WriteString(str_enclosure);
				}
				else
				{
					stream.WriteString(str_field);
				}
			}

			stream.WriteString("\n");

			return (initial_position == -1) ? stream.WritePosition : stream.WritePosition - initial_position;
		}

		#endregion

		#region fread, fgetc, fwrite, fputs, fpassthru, readfile

		///
		/// Binary-safe file read.
		///
		/// <param name="handle">A file stream opened for reading.</param>
		/// <param name="length">Number of bytes to be read.</param>
		/// <returns>
		/// The <see cref="string"/> or <see cref="PhpBytes"/>
		/// of the specified length depending on file access mode.
		/// </returns>
		/// <remarks>
		/// Result is affected by run-time quoting
		/// (<see cref="LocalConfiguration.VariablesSection.QuoteRuntimeVariables"/>).
		/// </remarks>
		[ImplementsFunction("fread")]
		public static object Read(PhpResource handle, int length)
		{
			// returns an object (string or PhpBytes depending on fopen mode)
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return null;

			if (stream.IsText)
				return Core.Convert.Quote(stream.ReadString(length), ScriptContext.CurrentContext);
			else
				return Core.Convert.Quote(stream.ReadBytes(length), ScriptContext.CurrentContext);
		}

		///
		/// Gets character from file pointer.
		///
		/// <param name="handle">A file stream opened for reading.</param>
		/// <returns>A <see cref="string"/> or <see cref="PhpBytes"/> containing one character from the
		/// given stream or <c>false</c> on EOF.</returns>
		[ImplementsFunction("fgetc")]
		[return: CastToFalse]
		public static object ReadChar(PhpResource handle)
		{
			if (Eof(handle)) return null;
			return Read(handle, 1);
		}

		///
		/// Binary-safe file write.
		///
		/// <param name="handle">The file stream (opened for writing). </param>
		/// <param name="data">The data to be written.</param>
		/// <returns>Returns the number of bytes written, or FALSE on error. </returns>
		/// <remarks>
		/// Affected by run-time quoting (data are unqouted before written)
		/// (<see cref="LocalConfiguration.VariablesSection.QuoteRuntimeVariables"/>).
		/// </remarks>
		[ImplementsFunction("fwrite")]
		[return: CastToFalse]
		public static int Write(PhpResource handle, object data)
		{
			return Write(handle, data, -1);
		}

		///
		/// Binary-safe file write.
		///
		/// <param name="handle">The file stream (opened for writing). </param>
		/// <param name="data">The data to be written.</param>
		/// <param name="length">
		/// If the length argument is given, writing will stop after length bytes
		/// have been written or the end of string is reached, whichever comes first.
		/// </param>
		/// <returns>Returns the number of bytes written, or FALSE on error. </returns>
		/// <remarks>
		/// Affected by run-time quoting (data are unqouted before written)
		/// (<see cref="LocalConfiguration.VariablesSection.QuoteRuntimeVariables"/>).
		/// </remarks>
		[ImplementsFunction("fwrite")]
		[return: CastToFalse]
		public static int Write(PhpResource handle, object data, int length)
		{
			data = Core.Convert.Unquote(data, ScriptContext.CurrentContext);
			return WriteInternal(handle, data, length);
		}

		///
		/// Binary-safe file write. Alias for <see cref="Write(PhpResource, object)"/>.
		///
		/// <param name="handle">The file stream (opened for writing). </param>
		/// <param name="data">The data to be written.</param>
		/// <returns>Returns the number of bytes written, or FALSE on error. </returns>
		[ImplementsFunction("fputs")]
		[return: CastToFalse]
		public static int Write2(PhpResource handle, object data)
		{
			return Write(handle, data);
		}

		///
		/// Binary-safe file write. Alias for <see cref="Write(PhpResource, object, int)"/>.
		///
		/// <param name="handle">The file stream (opened for writing). </param>
		/// <param name="data">The data to be written.</param>
		/// <param name="length">If the length argument is given, writing will stop after length bytes
		/// have been written or the end of string is reached, whichever comes first. </param>
		/// <returns>Returns the number of bytes written, or FALSE on error. </returns>
		[ImplementsFunction("fputs")]
		[return: CastToFalse]
		public static int Write2(PhpResource handle, object data, int length)
		{
			return Write(handle, data, length);
		}

		///
		/// Binary-safe file write implementation.
		///
		/// <param name="handle">The file stream (opened for writing). </param>
		/// <param name="data">The data to be written.</param>
		/// <param name="length">The number of characters to write or <c>-1</c> to use the whole <paramref name="data"/>.</param>
		/// <returns>Returns the number of bytes written, or FALSE on error. </returns>
		internal static int WriteInternal(PhpResource handle, object data, int length)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return -1;

			if (data == null) return 0;

			// Note: Any data type is converted using implicit conversion in AsText/AsBinary.
			if (stream.IsText)
			{
				// If file OpenMode is text then use string access methods.
				string sub;
				if (length > 0) sub = PhpStream.AsText(data, length);
				else sub = PhpStream.AsText(data);

				return stream.WriteString(sub);
			}
			else
			{
				// File OpenMode is binary.
				PhpBytes sub;
				if (length > 0) sub = PhpStream.AsBinary(data, length);
				else sub = PhpStream.AsBinary(data);

				return stream.WriteBytes(sub);
			}
		}

		///
		/// Outputs all remaining data on a file pointer.
		///
		/// <param name="handle">The file stream (opened for reading). </param>
		/// <returns>Number of bytes written.</returns>
		[ImplementsFunction("fpassthru")]
		[return: CastToFalse]
		public static int PassThrough(PhpResource handle)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return -1;
			if (stream.IsText)
			{
				// Use the text output buffers.
				int rv = 0;
				while (!stream.Eof)
				{
					string str = stream.ReadMaximumString();
					ScriptContext.CurrentContext.Output.Write(str);
					rv += str.Length;
				}
				return rv;
			}
			else
			{
				// Write directly to the binary output buffers.
				return PhpStreams.Copy(stream, InputOutputStreamWrapper.ScriptOutput);
			}
		}

		///
		/// Reads a file and writes it to the output buffer.
		///
		/// <param name="path">The file to open.</param>
		/// <returns>Returns the number of bytes read from the file. If an error occurs, <c>false</c> is returned.</returns>
		[ImplementsFunction("readfile")]
		[return: CastToFalse]
		public static int ReadFile(string path)
		{
			return ReadFile(path, FileOpenOptions.Empty, StreamContext.Default);
		}

		///
		/// Reads a file and writes it to the output buffer.
		///
		/// <param name="path">The file to open.</param>
		/// <param name="flags">Searches for the file in the <c>include_path</c> if set to <c>true</c>.</param>
		/// <returns>Returns the number of bytes read from the file. If an error occurs, <c>false</c> is returned.</returns>
		[ImplementsFunction("readfile")]
		[return: CastToFalse]
		public static int ReadFile(string path, FileOpenOptions flags)
		{
			return ReadFile(path, flags, StreamContext.Default);
		}

		///
		/// Reads a file and writes it to the output buffer.
		///
		/// <param name="path">The file to open.</param>
		/// <param name="flags">Searches for the file in the <c>include_path</c> if set to <c>1</c>.</param>
		/// <param name="context">A <see cref="StreamContext"/> resource with additional information for the stream.</param>
		/// <returns>Returns the number of bytes read from the file. If an error occurs, <c>false</c> is returned.</returns>
		[ImplementsFunction("readfile")]
		[return: CastToFalse]
		public static int ReadFile(string path, FileOpenOptions flags, PhpResource context)
		{
            StreamContext sc = StreamContext.GetValid(context, true);
			if (sc == null) return -1;

			using (PhpStream res = PhpStream.Open(path, "rb", ProcessOptions(flags), sc))
			{
				if (res == null) return -1;

				// Note: binary file access is the most efficient (no superfluous filtering
				// and no conversions - PassThrough will write directly to the OutputStream).
				return PassThrough(res);
			}
		}

		#endregion

		#region fgets, fgetss

		///
		/// Gets one line of text from file pointer including the end-of-line character.
		///
		/// <param name="handle">The file stream opened for reading.</param>
		/// <returns>A <see cref="string"/> or <see cref="PhpBytes"/> containing the line of text or <c>false</c> in case of an error.</returns>
		/// <remarks>
		/// <para>
		///   Result is affected by run-time quoting
		///   (<see cref="LocalConfiguration.VariablesSection.QuoteRuntimeVariables"/>).
		/// </para>
		/// </remarks>
		[ImplementsFunction("fgets")]
		[return: CastToFalse]
		public static object ReadLine(PhpResource handle)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return null;

			// Use the default accessor to the stream breaking at \n, no superfluous conversion.
			return Core.Convert.Quote(stream.ReadData(-1, true), ScriptContext.CurrentContext);
		}

		///
		/// Gets one line of text from file pointer including the end-of-line character.
		///
		/// <param name="length">Maximum length of the returned text.</param>
		/// <param name="handle">The file stream opened for reading.</param>
		/// <returns>A <see cref="string"/> or <see cref="PhpBytes"/> containing the line of text or <c>false</c> in case of an error.</returns>
		/// <remarks>
		/// <para>
		///   Returns a string of up to <paramref name="length"/><c> - 1</c> bytes read from
		///   the file pointed to by <paramref name="handle"/>.
		/// </para>
		/// <para>
		///   The <paramref name="length"/> parameter became optional in PHP 4.2.0, if omitted, it would
		///   assume 1024 as the line length. As of PHP 4.3, omitting <paramref name="length"/> will keep
		///   reading from the stream until it reaches the end of the line.
		///   If the majority of the lines in the file are all larger than 8KB,
		///   it is more resource efficient for your script to specify the maximum line length.
		/// </para>
		/// <para>
		///   Result is affected by run-time quoting
		///   (<see cref="LocalConfiguration.VariablesSection.QuoteRuntimeVariables"/>).
		/// </para>
		/// </remarks>
		[ImplementsFunction("fgets")]
		[return: CastToFalse]
		public static object ReadLine(PhpResource handle, int length)
		{
			if (length <= 0)
			{
				PhpException.Throw(PhpError.Warning, LibResources.GetString("arg:negative", "Length"));
				return null;
			}

			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return null;

			// Use the default accessor to the stream breaking at \n, no superfluous conversion.
			return Core.Convert.Quote(stream.ReadData(length, true), ScriptContext.CurrentContext);
		}

		///
		/// Gets a whole line from file pointer and strips HTML tags.
		///
		[ImplementsFunction("fgetss")]
		[return: CastToFalse]
		public static string ReadLineStripTags(PhpResource handle)
		{
			return ReadLineStripTagsInternal(handle, -1, null);
		}

		///
		/// Gets a line from file pointer and strips HTML tags.
		///
		[ImplementsFunction("fgetss")]
		[return: CastToFalse]
		public static string ReadLineStripTags(PhpResource handle, int length)
		{
			return ReadLineStripTags(handle, length, null);
		}

		///
		/// Gets one line from file pointer and strips HTML tags.
		///
		/// <param name="handle"></param>
		/// <param name="length"></param>
		/// <param name="allowableTags"></param>
		/// <returns></returns>
		[ImplementsFunction("fgetss")]
		[return: CastToFalse]
		public static string ReadLineStripTags(PhpResource handle, int length, string allowableTags)
		{
			if (length <= 0)
			{
				PhpException.Throw(PhpError.Warning, LibResources.GetString("arg:negative", "Length"));
				return null;
			}

			return ReadLineStripTagsInternal(handle, length, allowableTags);
		}

		internal static string ReadLineStripTagsInternal(PhpResource handle, int length, string allowableTags)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return null;
			string line = PhpStream.AsText(stream.ReadLine(length, null));

			if (line != null)
			{
				int state = stream.StripTagsState;
				line = PhpStrings.StripTags(line, allowableTags, ref state);
				stream.StripTagsState = state;
			}
			return line;
		}

		#endregion

		#region file, file_get_contents, file_put_contents

		///
		/// Reads entire file into an array.
		///
		/// <param name="path"></param>
		/// <returns></returns>
		[ImplementsFunction("file")]
		[return: CastToFalse]
		public static PhpArray ReadArray(string path)
		{
			return ReadArray(path, 0, StreamContext.Default);
		}

		///
		/// Reads entire file into an array.
		///
		/// <param name="path"></param>
		/// <param name="flags"></param>
		/// <returns></returns>
		[ImplementsFunction("file")]
		[return: CastToFalse]
		public static PhpArray ReadArray(string path, FileOptions flags)
		{
			return ReadArray(path, flags, StreamContext.Default);
		}

		///
		/// Reads entire file into an array.
		///
		/// <remarks>
		/// </remarks>
		/// <para>
		///   The input file is split at '\n' and the separator is included in every line.
		/// </para>
		/// <para>
		///   Result is affected by run-time quoting
		///   (<see cref="LocalConfiguration.VariablesSection.QuoteRuntimeVariables"/>).
		/// </para>
		[ImplementsFunction("file")]
		[return: CastToFalse]
		public static PhpArray ReadArray(string path, FileOptions flags, PhpResource context)
		{
            StreamContext sc = StreamContext.GetValid(context, true);
			if (sc == null) return null;

			ScriptContext script_context = ScriptContext.CurrentContext;

			using (PhpStream stream = PhpStream.Open(path, "rt", ProcessOptions((FileOpenOptions)flags), sc))
			{
				if (stream == null) return null;

				PhpArray rv = new PhpArray();

				while (!stream.Eof)
				{
					// Note: The last line does not contain the \n delimiter, but may be empty
					string line = PhpStream.AsText(stream.ReadData(-1, true));

                    if ((flags & FileOptions.TrimLineEndings) > 0)
                    {
                        int len = line.Length;
                        if ((len > 0) && (line[len - 1] == '\n'))
                            line = line.Substring(0, len - 1);
                    }
                    if ((flags & FileOptions.SkipEmptyLines) > 0)
					{
						if (line.Length == 0) continue;
					}

					rv.Add(Core.Convert.Quote(line, script_context));
				}

				return rv;
			}
		}

		///
		/// Reads entire file into a string.
		///
        [ImplementsFunction("file_get_contents", FunctionImplOptions.NeedsVariables)]
		[return: CastToFalse]
        public static object ReadContents(ScriptContext scriptcontext, System.Collections.Generic.Dictionary<string, object> definedVariables, string path)
		{
            return ReadContents(scriptcontext, definedVariables, path, FileOpenOptions.Empty, StreamContext.Default, -1, -1);
		}

		///
		/// Reads entire file into a string.
		///
        [ImplementsFunction("file_get_contents", FunctionImplOptions.NeedsVariables)]
		[return: CastToFalse]
        public static object ReadContents(ScriptContext scriptcontext, System.Collections.Generic.Dictionary<string, object> definedVariables, string path, FileOpenOptions flags)
		{
            return ReadContents(scriptcontext, definedVariables, path, flags, StreamContext.Default, -1, -1);
		}

		///
		/// Reads entire file into a string.
		///
        [ImplementsFunction("file_get_contents", FunctionImplOptions.NeedsVariables)]
		[return: CastToFalse]
        public static object ReadContents(ScriptContext scriptcontext, System.Collections.Generic.Dictionary<string, object> definedVariables, string path, FileOpenOptions flags, PhpResource context)
		{
            return ReadContents(scriptcontext, definedVariables, path, flags, context, -1, -1);
		}

		///
		/// Reads entire file into a string.
		///
        [ImplementsFunction("file_get_contents", FunctionImplOptions.NeedsVariables)]
		[return: CastToFalse]
        public static object ReadContents(ScriptContext scriptcontext, System.Collections.Generic.Dictionary<string, object> definedVariables, string path, FileOpenOptions flags, PhpResource context,
		  int offset)
		{
            return ReadContents(scriptcontext, definedVariables, path, flags, context, offset, -1);
		}

		///
		/// Reads entire file into a string.
		///
		/// <remarks>
		/// Result is affected by run-time quoting
		/// (<see cref="LocalConfiguration.VariablesSection.QuoteRuntimeVariables"/>).
		/// </remarks>
        [ImplementsFunction("file_get_contents", FunctionImplOptions.NeedsVariables)]
		[return: CastToFalse]
		public static object ReadContents(ScriptContext scriptcontext, System.Collections.Generic.Dictionary<string, object> definedVariables, string path, FileOpenOptions flags, PhpResource context,
		  int offset, int maxLength)
		{
            StreamContext sc = StreamContext.GetValid(context, true);
            if (sc == null)
                return null;

			using (PhpStream stream = PhpStream.Open(path, "rb", ProcessOptions(flags), sc))
			{
				if (stream == null) return null;

                // when HTTP protocol requested, store responded headers into local variable $http_response_header:
                // NOTE: (J) this should be applied by HTTP wrapper itself, not only by this function.
                if (string.Compare(stream.Wrapper.Scheme, "http", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    var headers = stream.WrapperSpecificData as PhpArray;
                    Operators.SetVariable(scriptcontext, definedVariables, HttpResponseHeaderName, headers);
                }

                //
				return Core.Convert.Quote(stream.ReadContents(maxLength, offset), ScriptContext.CurrentContext);
			}
		}

		[ImplementsFunction("file_put_contents")]
		[return: CastToFalse]
		public static int WriteContents(string path, object data)
		{
			return WriteContents(path, data, 0, StreamContext.Default);
		}

		[ImplementsFunction("file_put_contents")]
		[return: CastToFalse]
		public static int WriteContents(string path, object data, WriteContentsOptions flags)
		{
			return WriteContents(path, data, flags, StreamContext.Default);
		}

		[ImplementsFunction("file_put_contents")]
		[return: CastToFalse]
		public static int WriteContents(string path, object data, WriteContentsOptions flags, PhpResource context)
		{
            StreamContext sc = StreamContext.GetValid(context, true);
			if (sc == null) return -1;

			string mode = (flags & WriteContentsOptions.AppendContents) > 0 ? "ab" : "wb";
			using (PhpStream to = PhpStream.Open(path, mode, ProcessOptions((FileOpenOptions)flags), sc))
			{
				if (to == null) return -1;

				// passing array is equivalent to file_put_contents($filename, join('', $array))
				PhpArray array = data as PhpArray;
				if (array != null)
				{
					int total = 0;

					foreach (object o in array.Values)
					{
						int written = to.WriteBytes(Core.Convert.ObjectToPhpBytes(o));
						if (written == -1) return total;
						total += written;
					}

					return total;
				}

				// as of PHP 5.1.0, you may also pass a stream resource to the data parameter
				PhpResource resource = data as PhpResource;
				if (resource != null)
				{
					PhpStream from = PhpStream.GetValid(resource);
					if (from == null) return -1;

					return PhpStreams.Copy(from, to);
				}

				return to.WriteBytes(Core.Convert.ObjectToPhpBytes(data));
			}
		}

		#endregion

		#region Seek (fseek, rewind, ftell, ftruncate)

		///
		/// Seeks on a file pointer.
		///
		/// <param name="handle">The file stream resource.</param>
		/// <param name="offset">The number of bytes to seek.</param>
		/// <returns>Upon success, returns 0; otherwise, returns -1.
		/// Note that seeking past EOF is not considered an error.</returns>
		[ImplementsFunction("fseek")]
		public static int Seek(PhpResource handle, int offset)
		{
			return Seek(handle, offset, (int)SeekOptions.Set);
		}

		///
		/// Seeks on a file pointer.
		///
		/// <param name="handle">A file stream resource.</param>
		/// <param name="offset">The number of bytes to seek.</param>
		/// <param name="whence">The position in stream to seek from.
		/// May be one of the SeekOptions flags.</param>
		/// <returns>Upon success, returns 0; otherwise, returns -1.
		/// Note that seeking past EOF is not considered an error.</returns>
		[ImplementsFunction("fseek")]
		public static int Seek(PhpResource handle, int offset, int whence)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return -1;
			return stream.Seek(offset, (SeekOrigin)whence) ? 0 : -1;
		}

		///
		/// Rewind the position of a file pointer.
		///
		/// <param name="handle"></param>
		/// <returns></returns>
		[ImplementsFunction("rewind")]
		public static bool Rewind(PhpResource handle)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return false;
			return stream.Seek(0, SeekOrigin.Begin);
		}

		///
		/// Tells file pointer read/write position.
		///
		/// <param name="handle">A file stream resource.</param>
		/// <returns></returns>
		[ImplementsFunction("ftell")]
		[return: CastToFalse]
		public static int Tell(PhpResource handle)
		{
			PhpStream stream = PhpStream.GetValid(handle);
			if (stream == null) return -1;
			return stream.Tell();
		}

		///
		/// Truncates a file to a given length.
		///
		/// <param name="handle"></param>
		/// <param name="size"></param>
		/// <returns></returns>
		[ImplementsFunction("ftruncate")]
		public static bool Truncate(PhpResource handle, int size)
		{
            PhpStream stream = PhpStream.GetValid(handle);
            if (stream == null) return false;

            if (stream.RawStream != null && stream.RawStream.CanWrite && stream.RawStream.CanSeek)
            {
                stream.RawStream.SetLength(size);
                return true;
            }

            return false;
		}

		#endregion

		#region FileSystem Access (copy, rename, unlink, mkdir, rmdir, flock)

		///
		/// Copies a file (even accross different stream wrappers).
		///
		/// <remarks>
		/// If the destination file already exists, it will be overwritten.
		/// <para>
		/// Note: As of PHP 4.3.0, both source and dest may be URLs if the
		/// "fopen wrappers" have been enabled. See <c>fopen()</c> for more details.
		/// If dest is an URL, the copy operation may fail if the wrapper does
		/// not support overwriting of existing files.
		/// </para>
		/// </remarks>
		/// <param name="source">Source URL.</param>
		/// <param name="dest">Destination URL.</param>
		/// <returns><c>true</c> on success or <c>false</c> on failure.</returns>
		[ImplementsFunction("copy")]
		public static bool Copy(string source, string dest)
		{
			StreamWrapper reader, writer;
			if ((!PhpStream.ResolvePath(ref source, out reader, CheckAccessMode.FileExists, CheckAccessOptions.Empty))
				|| (!PhpStream.ResolvePath(ref dest, out writer, CheckAccessMode.FileExists, CheckAccessOptions.Empty)))
				return false;

			if ((reader.Scheme == "file") && (writer.Scheme == "file"))
			{
				// Copy the file.
				try
				{
					File.Copy(source, dest, true);
					return true;
				}
				catch (System.Exception)
				{
					return false;
				}
			}
			else
			{
				// Copy the two files using the appropriate stream wrappers.
				using (PhpResource from = reader.Open(ref source, "rb", StreamOpenOptions.Empty, StreamContext.Default))
				{
					if (from == null) return false;
					using (PhpResource to = writer.Open(ref dest, "wb", StreamOpenOptions.Empty, StreamContext.Default))
					{
						if (to == null) return false;

						int copied = PhpStreams.Copy(from, to);
						return copied >= 0;
					}
				}
			}
		}

		///
		/// Renames a file.
		///
		/// <remarks>
		/// Both the <paramref name="oldpath"/> and the <paramref name="newpath"/>
		/// must be handled by the same wrapper.
		/// </remarks>
		/// <param name="oldpath"></param>
		/// <param name="newpath"></param>
		/// <returns></returns>
		[ImplementsFunction("rename")]
		public static bool Rename(string oldpath, string newpath)
		{
			StreamWrapper oldwrapper, newwrapper;
			if ((!PhpStream.ResolvePath(ref oldpath, out oldwrapper, CheckAccessMode.FileExists, CheckAccessOptions.Empty))
				|| (!PhpStream.ResolvePath(ref newpath, out newwrapper, CheckAccessMode.FileMayExist, CheckAccessOptions.Empty)))
				return false;

			if (oldwrapper != newwrapper)
			{
				PhpException.Throw(PhpError.Warning, LibResources.GetString("wrappers_must_match"));
			}

			return oldwrapper.Rename(oldpath, newpath, StreamRenameOptions.Empty, StreamContext.Default);
		}

		///
		/// Deletes a file using a StreamWrapper corresponding to the given URL.
		///
		/// <param name="path">An URL of a file to be deleted.</param>
		/// <returns>True in case of success.</returns>
		[ImplementsFunction("unlink")]
		public static bool Delete(string path)
		{
            return Delete(path, null);
		}

        ///
        /// Deletes a file using a StreamWrapper corresponding to the given URL.
        ///
        /// <param name="path">An URL of a file to be deleted.</param>
        /// <param name="context">StreamContext.</param>
        /// <returns>True in case of success.</returns>
        [ImplementsFunction("unlink")]
        public static bool Delete(string path, PhpResource context)
        {
            if (String.IsNullOrEmpty(path))
            {
                PhpException.Throw(PhpError.Warning, LibResources.GetString("arg:empty", "path"));
                return false;
            }

            StreamContext sc = StreamContext.GetValid(context, true);
            if (sc == null) // PHP warning is thrown by StreamContext.GetValid
                return false;

            StreamWrapper wrapper;
            if (!PhpStream.ResolvePath(ref path, out wrapper, CheckAccessMode.FileExists, CheckAccessOptions.Empty))
                return false;

            // Clear the cache (the currently deleted file may have been cached)
#if !SILVERLIGHT
            ClearStatCache();
#endif
            return wrapper.Unlink(path, 0, sc);
        }

		///
		///
		///
		/// <param name="handle"></param>
		/// <param name="operation"></param>
		/// <returns></returns>
        [ImplementsFunction("flock")]
		public static bool Lock(PhpResource handle, int operation)
		{
			int dummy = 0;
			return Lock(handle, operation, ref dummy);
		}

        ///
        /// Portable advisory file locking.
        ///
        /// <param name="handle">A file system pointer resource that is typically created using fopen().</param>
        /// <param name="operation">Operation is one of the following:
        /// <c>LOCK_SH</c> to acquire a shared lock (reader).
        /// <c>LOCK_EX</c> to acquire an exclusive lock (writer).
        /// <c>LOCK_UN</c> to release a lock (shared or exclusive).
        ///
        /// It is also possible to add <c>LOCK_NB</c> as a bitmask to one of the above operations if you don't want flock() to block while locking. (not supported on Windows)
        /// </param>
        /// <param name="wouldblock">The optional third argument is set to TRUE if the lock would block (EWOULDBLOCK errno condition). (not supported on Windows)</param>
        /// <returns>Returns <c>true</c> on success or <c>false</c> on failure.</returns>
        [ImplementsFunction("flock")]
        public static bool Lock(PhpResource handle, int operation, ref int wouldblock)
        {
            // Get the native file handle for the PHP resource
            var phpStream = PhpStream.GetValid(handle);
            if (phpStream == null) return false;

            var fileStream = phpStream.RawStream as FileStream;
            if (fileStream == null) return false;

            //
            if (EnvironmentUtils.IsDotNetFramework)
            {
                return Lock_dotNET(fileStream, (StreamLockOptions)operation);
            }
            else
            {
                PhpException.FunctionNotSupported();
                return false;
            }
        }

        #region flock (Windows)

        // Constants passed to LockFileEx for the flags
        private const uint LOCKFILE_FAIL_IMMEDIATELY = 0x00000001;
        private const uint LOCKFILE_EXCLUSIVE_LOCK = 0x00000002;

        [DllImport("kernel32.dll")]
        static extern bool LockFileEx(SafeFileHandle hFile, uint dwFlags, uint dwReserved, uint nNumberOfBytesToLockLow, uint nNumberOfBytesToLockHigh, [In] ref NativeOverlapped lpOverlapped);

        [DllImport("kernel32.dll")]
        static extern bool UnlockFileEx(SafeFileHandle hFile, uint dwReserved, uint nNumberOfBytesToUnlockLow, uint nNumberOfBytesToUnlockHigh, [In] ref NativeOverlapped lpOverlapped);

        private static bool Lock_dotNET(FileStream/*!*/fileStream, StreamLockOptions op)
        {
            Debug.Assert(fileStream != null);

            var hFile = fileStream.SafeFileHandle;

            // Set up some parameters
            uint low = 1, high = 0;
            var offset = new NativeOverlapped();
            bool noBlocking = (op & StreamLockOptions.NoBlocking) != 0;

            // bug for bug compatible with Unix
            UnlockFileEx(hFile, 0, low, high, ref offset);

            //
            switch (op & ~StreamLockOptions.NoBlocking)
            {
                case StreamLockOptions.Exclusive:
                    // Exclusive lock
                    return LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK + (noBlocking ? LOCKFILE_FAIL_IMMEDIATELY : 0), 0, low, high, ref offset);

                case StreamLockOptions.Shared:
                    // Shared lock
                    return LockFileEx(hFile, (noBlocking ? LOCKFILE_FAIL_IMMEDIATELY : 0), 0, low, high, ref offset);

                case StreamLockOptions.Unlock:
                    // Unlock always succeeds
                    return true;
            }

            // Bad call
            return false;
        }

        #endregion

        #endregion
    }
}


text:
from __future__ import absolute_import

class FantasySport(object):
    """FantasySport Class
    """

    url = 'http://fantasysports.yahooapis.com/fantasy/v2/'

    def __init__(self, oauth, fmt=None, use_login=False):
        """Initialize a FantasySport object
        """
        self.oauth = oauth
        self.fmt = 'json' if not fmt else fmt  # JSON as default format
        self.use_login = use_login

    def __repr__(self,):
        return "<{0}> <{1}>".format(self.url, self.fmt)

    def _check_token_validity(self,):
        """Check wether or not the access token is still valid, if not, renews it
        """
        if not self.oauth.token_is_valid():
            self.oauth.refresh_access_token
        return True

    def _get(self, uri):
        """
        """

        if not self.oauth.oauth.base_url :
            self.oauth.oauth.base_url = self.url

        self._check_token_validity()

        response = self.oauth.session.get(uri, params={'format': self.fmt})

        return response

    def _put(self, uri, roster):
        """
        - uri : roster resource uri
        - roster : roster object
        """
        headers = {'Content-Type':'application/{0}'.format(self.fmt)}
        data = roster.to_json() if self.fmt == 'json' else roster.to_xml() # Getting roster xml or json according to self.fmt

        response = self.oauth.session.put(uri, data=data, headers=headers)

    def _add_login(self, uri):
        """Add users;use_login=1/ to the uri
        """
        uri = "users;use_login=1/{0}".format(uri)

        return uri

    def _format_resources_key(self, keys):
        """Format resources keys
        """
        return ','.join(str(e) for e in keys)

    def _build_uri(self, resources, keys, sub=None):
        """Build uri
        """
        if resources:
            uri = "{0}={1}".format(resources, self._format_resources_key(keys))
        else:
           uri = '{0}'.format(self._format_resources_key(keys))

        if sub and isinstance(sub, str) :
            uri += "/{0}".format(sub)
        if sub and not isinstance(sub, str):
            uri += ";out={0}".format(','.join([e for e in sub]))

        if self.use_login:
            uri = self._add_login(uri)

        return uri

    def get_collections(self, resource_type, resource_ids, sub_resources):
        """Generic method to get collections
        """
        uri = self._build_uri(resource_type, resource_ids, sub=sub_resources)
        response = self._get(uri)
        return response

    #################################
    #
    #           GAMES
    #
    #################################

    def get_games_info(self, game_keys, leagues=None, teams=False, players=None):
        """Return game info
        >>> yfs.get_games_info('mlb')
        Must set use_login to True to pull teams data
        """
        uri = self._build_uri('games;game_keys', game_keys)

        if leagues:
            uri += '/leagues;league_keys={0}'.format(leagues)

        if teams:
            uri += '/teams'

        if players:
            uri += '/players;player_keys={0}'.format(players)

        response = self._get(uri)

        return response

    ####################################
    #
    #           LEAGUES
    #
    ####################################
    def get_leagues(self, league_keys):
        """Return league data
        >>> yfs.get_leagues(['league_key'])
        """
        uri = self._build_uri('leagues;league_keys',league_keys)
        response = self._get(uri)
        return response

    def get_leagues_teams(self, league_keys):
        """Return leagues teams
        >>> yfs.get_leagues_teams(['238.l.627062'])
        """
        uri = self._build_uri('leagues;league_keys', league_keys, sub='teams')
        response = self._get(uri)
        return response

    def get_leagues_players(self, league_keys):
        """Return leagues players
        >>> yfs.get_leagues_teams(['238.l.627062'])
        """
        uri = self._build_uri('leagues;league_keys', league_keys, sub='players')
        response = self._get(uri)
        return response

    def get_leagues_scoreboard(self, league_keys, week=None):
        """Return leagues scoreboard
        >>> yfs.get_leagues_scoreboard(['league_key'])
        """
        uri = self._build_uri('leagues;league_keys',league_keys, sub='scoreboard')

        if week:
            uri += ';week={0}'.format(week)

        response = self._get(uri)
        return response

    def get_leagues_settings(self, league_keys):
        """Return leagues settings
        >>> yfs.get_leagues_settings(['238.l.627062','238.l.627062'])
        """
        uri = self._build_uri('leagues;league_keys', league_keys, sub='settings')
        response = self._get(uri)
        return response

    def get_leagues_standings(self, league_keys, teams=None, players=None):
        """Return leagues settings
        >>> yfs.get_leagues_settings(['238.l.627062','238.l.627062'])
        """
        uri = self._build_uri('leagues;league_keys', league_keys, sub='standings')

        if teams:
            uri += '/teams/{0}'.format(teams)

        if teams=='roster' and players:
            uri += '/players/{0}'.format(players)

        response = self._get(uri)
        return response

    def get_leagues_transactions(self, league_keys):
        """Return leagues settings
        >>> yfs.get_leagues_transactions(['238.l.627062'])
        """
        uri = self._build_uri('leagues;league_keys', league_keys, sub='transactions')
        response = self._get(uri)
        return response

    def get_leagues_draftresults(self, league_keys):
        """Return leagues draftresults
        >>> yfs.get_leagues_draftresults(['238.l.627062'])
        """
        uri = self._build_uri('leagues;league_keys', league_keys, sub='draftresults')
        response = self._get(uri)
        return response

    #########################################
    #
    #       PLAYERS (not league specific)
    #
    #########################################

    def get_players(self, player_keys, filters=None):
        """Return player data
        >>> yfs.get_players(['player_key'])
        """
        uri = self._build_uri('players;player_keys', player_keys)

        if filters and isinstance(filters, str):
            uri += ';{0}'.format(filters)
        if filters and not isinstance(filters, str):
            uri += ";{0}".format(','.join([e for e in filters]))

        response = self._get(uri)
        return response

    def get_players_stats(self, player_keys, week=None):
        """Return player stats (not league specific)
        >>> yfs.get_players_stats(['223.p.5479'], week=3)
        """
        uri = self._build_uri('players;player_keys', player_keys, sub='stats')

        if week:
            uri += ';type=week;week={0}'.format(week)

        response = self._get(uri)
        return response

    def get_players_percent_owned(self, player_keys):
        """Return ownership percentage of player (not league specific)
        >>> yfs.get_players_percent_owned([223.p.5479])
        """
        uri = self._build_uri('players;player_keys', player_keys, sub='percent_owned')
        response = self._get(uri)
        return response

    def get_players_draft_analysis(self, player_keys):
        """Return draft metrics for player (not league specific)
        >>> yfs.get_players_draft_analysis([223.p.5479])
        """
        uri = self._build_uri('players;player_keys', player_keys, sub='draft_analysis')
        response = self._get(uri)
        return response

    ###################################
    #
    #           TEAMS
    #
    ###################################

    def get_teams(self, team_keys):
        """Return team data
        >>> yfs.get_teams(['league_key'])
        """
        uri = self._build_uri('teams;team_keys',team_keys)
        response = self._get(uri)
        return response

    def get_teams_players(self, team_keys):
        """Return teams players
        >>> yfs.get_teams_players(['238.l.627062'])
        """
        uri = self._build_uri('teams;team_keys', team_keys, sub='players')
        response = self._get(uri)
        return response

    def get_teams_stats(self, team_keys, week=None):
        """Return team stats (week only for H2H league)
        >>> yfs.get_teams_stats(['238.l.627062.t.1'], week=3)
        """
        uri = self._build_uri('teams;team_keys',team_keys, sub='stats')

        if week:
            uri += ';type=week;week={0}'.format(week)

        response = self._get(uri)
        return response

    def get_teams_standings(self, team_keys):
        """Return team standings
        >>> yfs.get_teams_standings(['238.l.627062.t.1'])
        """
        uri = self._build_uri('teams;team_keys',team_keys, sub='standings')
        response = self._get(uri)
        return response

    def get_teams_roster(self, team_keys, week=None, players=None, filters=None):
        """Return team roster
        >>> yfs.get_teams_roster(['238.l.627062.t.1'], week=3)
        """
        uri = self._build_uri('teams;team_keys',team_keys, sub='roster')

        if week:
            uri += ';week={0}'.format(week)

        if players and filters:
            uri += '/players;{1}/{0}'.format(filters, players)

        elif filters and not players:
            uri += '/players;{0}'.format(filters)

        elif players and not filters:
            uri += '/players/{0}'.format(players)

        response = self._get(uri)
        return response

    def get_teams_draftresults(self, team_keys):
        """Return a team's draft results
        >>> yfs.get_teams_draftresults(['238.l.627062.t.1'])
        """
        uri = self._build_uri('teams;team_keys',team_keys, sub='draftresults')
        response = self._get(uri)
        return response

    def get_teams_matchups(self, team_keys, weeks=None):
        """Return team matchups (H2H leagues only)
        >>> yfs.get_teams_matchups(['238.l.627062.t.1'], weeks='1,3,6')
        """
        uri = self._build_uri('teams;team_keys',team_keys, sub='matchups')

        if weeks and isinstance(weeks, str):
            uri += ';weeks={0}'.format(weeks)
        if weeks and not isinstance(weeks, str):
            uri += ";weeks{0}".format(','.join([e for e in weeks]))

        response = self._get(uri)
        return response

    ##############################################
    #
    #    ROSTERS (team specific player info)
    #
    ##############################################

    def get_roster_players(self, team_keys, week=None, date=None):
        """Access roster info, with player sub option
        >>> yfs.get_roster_players(['238.l.627062'])
        """
        uri = self._build_uri(None, team_keys, sub='roster/players')
        uri = 'team/{0}'.format(uri) # Done to avoid having 'team=238.l.627062', which doesn't work for this resource

        if week:
            uri += ';week={0}'.format(week)
        if date:
            uri += ';date={0}'.format(date)

        response = self._get(uri)
        return response

    def set_roster_players(self, team_keys, roster):
        """
        >>> from fantasy_sport import Roster, Player
        >>> p1 = Player('242.p.8332','WR')
        >>> p2 = Player('242.p.8334','WL')
        >>> roster = Roster([p1, p2], date='2015-01-11')
        >>> ysf.set_roster_players(['238.l.627062'], roster)
        """
        uri = self._build_uri(None, team_keys, sub='roster/players')
        uri = 'team/{0}'.format(uri)

        response = self._put(uri, roster)
        return response

    ##############################################
    #
    #    TRANSACTIONS
    #
    ##############################################

    def get_transactions(self, transaction_keys, players=None):
        """Return transaction data
        >>> yfs.get_transaction(['transaction_key'])
        """

        if players:
            subtext = 'players/{0}'.format(players)
            uri = self._build_uri('transactions;transaction_keys', transaction_keys, sub=subtext)
        else:
            uri = self._build_uri('transactions;transaction_keys', transaction_keys)

        response = self._get(uri)
        return response

redpajama_set_name: RedPajamaGithub


text:
import gulp = require('gulp');
import minifyHtml = require('gulp-minify-html');

minifyHtml();
minifyHtml({conditionals: true, loose: true});

gulp.task('minify-html', () => {
    var opts = {
        conditionals: true,
        spare: true
    };

    return gulp.src('./static/html/*.html')
        .pipe(minifyHtml(opts))
        .pipe(gulp.dest('./dist/'));
});


text:
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using BookStore.Domain;
using System.Data.SqlClient;
using BookStore.Properties;
using BookStore.Util;

namespace BookStore.Tests
{
    [TestFixture]
    public class BooksTest : BaseTest
    {
        [Test]
        public void List_Of_Books_From_EmptyLibrary_Has_No_Books()
        {
            Library library = CreateTestLibrary();
            ICollection<Book> books = library.GetBooks();
            Assert.AreEqual(0, books.Count);
        }

        [Test]
        public void Can_Add_Book_To_Library()
        {
            Library library = CreateTestLibrary();
            library.AddBook(CreateBook());
            ICollection<Book> books = library.GetBooks();
            Assert.AreEqual(1, books.Count);
        }

        [Test]
        public void Book_Has_Name_Settable_From_Constructor()
        {
            Book book = CreateBook();
            Assert.AreEqual("War & Peace", book.Name);
        }

        [Test]
        public void Add_New_Book_Will_Create_A_Single_Copy()
        {
            Library library = CreateTestLibrary();
            Book book = CreateBook();

            library.AddBook(book);

            int copies = library.GetNumberOfCopies(book);

            Assert.AreEqual(1, copies);
        }

        private static Book CreateBook()
        {
            return new Book("1-1231-13", "War & Peace");
        }

        private static Library CreateTestLibrary()
        {
            return new Library();
        }

        [Test]
        public void Add_New_Copy_Of_Book()
        {
            Library library = CreateTestLibrary();
            Book book = CreateBook();

            library.AddBook(book);
            library.AddBookCopy(book);
            int copies = library.GetNumberOfCopies(book);

            Assert.AreEqual(2, copies);
        }

        [Test]
        public void Get_Book_List()
        {
            Library library = CreateTestLibrary();
            Book book1 = new Book("1-1231-13", "War & Peace vol 1");
            Book book2 = new Book("1-1231-14", "War & Peace vol 2");
            Book book3 = new Book("1-1231-15", "War & Peace vol 3");

            library.AddBook(book1);
            library.AddBook(book2);
            library.AddBook(book3);

            IList<Book> bl = library.GetBookList();

            Assert.AreEqual("War & Peace vol 2", bl[1].Name);
        }

        [Test]
        public void Get_Book_Copies()
        {
            Library library = CreateTestLibrary();
            Book book1 = new Book("1-1231-13", "War & Peace vol 1");

            library.AddBook(book1);
            library.AddBookCopy(book1);
            library.AddBookCopy(book1);

            IList<BookCopy> bcl = library.GetBookCopies(book1);

            Assert.AreEqual(3, bcl.Count);
        }

        [Test]
        public void Get_Book_By_ID()
        {
            Library library = CreateTestLibrary();
            Book book1 = new Book("1-1231-13", "War & Peace vol 1");
            Book book2;
            library.AddBook(book1);

            book2 = library.GetBookByISBN("1-1231-13");
            Assert.AreEqual(book1.Name, book2.Name);
        }

        [Test]
        public void Add_Book_And_Five_Copies_With_Single_Transaction()
        {
            With.TotalOpenedTransactionCount = 0;

            With.Transaction(delegate
            {
                Library library = CreateTestLibrary();
                Book book1 = new Book("1-1231-13", "War & Peace vol 1");
                library.AddBook(book1);
                for (int i = 0; i < 4; i++)
                    library.AddBookCopy(book1);

            });

            Assert.AreEqual(1, With.TotalOpenedTransactionCount);
        }

        [Test]
        public void Can_Check_A_Book_From_Library()
        {
            Library library = CreateTestLibrary();
            Book book1 = new Book("1-1231-13", "War & Peace vol 1");
            library.AddBook(book1);

            User user = new User("read-alot", "read", "a lot");
            library.AddUser(user);

            ICollection<Book> books = library.GetBooksCheckedOutBy(user);
            Assert.AreEqual(0, books.Count);

            library.CheckOutCopyOf(book1, user);

            books = library.GetBooksCheckedOutBy(user);
            Assert.AreEqual(1, books.Count);
        }
    }
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>H-Index</title>
<meta name="date" content="2022-10-12">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Letter

Next Letter

Frames

No Frames

All Classes

B C D E F G H I J M P R S T U V W X

H

hashCode() - Method in class com.mgnt.utils.textutils.Version

HttpClient - Class in com.mgnt.lifecycle.management.httpclient

This class is meant to be a parent class to any class that wants to implement an http access to a particular
 cite.

HttpClient() - Constructor for class com.mgnt.lifecycle.management.httpclient.HttpClient

HttpClient.HttpMethod - Enum in com.mgnt.lifecycle.management.httpclient

B C D E F G H I J M P R S T U V W X

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Letter

Next Letter

Frames

No Frames

All Classes


text: ```We don't know what this gonna be yet```


text:
Rendering snapshots
===================

.. js:function:: LC.renderSnapshotToImage(snapshot, options)

  .. versionadded:: 0.4.9

  Render the snapshot to a canvas. To turn the result into an image URL,
  call ``toDataURL()`` on the result.

  **Options**

  ``rect``
    A dict ``{x, y, width, height}`` specifying which part of the image to
    draw, in drawing coordinates (before scaling). Defaults to the bounding
    box of all shapes. If you don't specify a ``rect`` and there are no
    shapes in the drawing, :js:func:`getImage` will return ``undefined``.

  ``margin``
    A dict ``{top, right, bottom, left}`` defaulting to ``null``. If the
    image's bounds are determined by the shapes' bounding rect (i.e. ``rect``
    is not given), this dict determines the amount of space on each side.

  ``scale``
    Amount by which to scale the image output. Shapes will be rendered at
    full resolution. Defaults to ``1``.

  ``watermarkImage``
    Image to render in the center behind everything, unaffected by erasers.

  ``watermarkScale``
    Scale of the watermark.

.. js:function:: LC.renderSnapshotToSVG(snapshot, options)

  .. versionadded:: 0.4.9

  Render the snapshot to an SVG string that can be inserted into the DOM or
  downloaded.

  .. warning::

    SVG export does not currently support watermarks, scale, or eraser shapes.

  **Options**

  ``rect``
    A dict ``{x, y, width, height}`` specifying which part of the image to
    draw, in drawing coordinates (before scaling). Defaults to the bounding
    box of all shapes. If you don't specify a ``rect`` and there are no
    shapes in the drawing, :js:func:`getImage` will return ``undefined``.

  ``margin``
    A dict ``{top, right, bottom, left}`` defaulting to ``null``. If the
    image's bounds are determined by the shapes' bounding rect (i.e. ``rect``
    is not given), this dict determines the amount of space on each side.


text:
package com.amazonaws.services.glacier.model.transform;

import java.math.*;

import javax.annotation.Generated;

import com.amazonaws.services.glacier.model.*;
import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.*;
import com.amazonaws.transform.*;

import com.fasterxml.jackson.core.JsonToken;
import static com.fasterxml.jackson.core.JsonToken.*;

/**
 * InputSerialization JSON Unmarshaller
 */
@Generated("com.amazonaws:aws-java-sdk-code-generator")
public class InputSerializationJsonUnmarshaller implements Unmarshaller<InputSerialization, JsonUnmarshallerContext> {

    public InputSerialization unmarshall(JsonUnmarshallerContext context) throws Exception {
        InputSerialization inputSerialization = new InputSerialization();

        int originalDepth = context.getCurrentDepth();
        String currentParentElement = context.getCurrentParentElement();
        int targetDepth = originalDepth + 1;

        JsonToken token = context.getCurrentToken();
        if (token == null)
            token = context.nextToken();
        if (token == VALUE_NULL) {
            return null;
        }

        while (true) {
            if (token == null)
                break;

            if (token == FIELD_NAME || token == START_OBJECT) {
                if (context.testExpression("csv", targetDepth)) {
                    context.nextToken();
                    inputSerialization.setCsv(CSVInputJsonUnmarshaller.getInstance().unmarshall(context));
                }
            } else if (token == END_ARRAY || token == END_OBJECT) {
                if (context.getLastParsedParentElement() == null || context.getLastParsedParentElement().equals(currentParentElement)) {
                    if (context.getCurrentDepth() <= originalDepth)
                        break;
                }
            }
            token = context.nextToken();
        }

        return inputSerialization;
    }

    private static InputSerializationJsonUnmarshaller instance;

    public static InputSerializationJsonUnmarshaller getInstance() {
        if (instance == null)
            instance = new InputSerializationJsonUnmarshaller();
        return instance;
    }
}


text:
package org.kie.workbench.common.screens.datamodeller.client;

import java.util.ArrayList;
import java.util.List;

import com.google.gwtmockito.GwtMock;
import com.google.gwtmockito.GwtMockitoTestRunner;
import org.guvnor.common.services.shared.metadata.model.Overview;
import org.guvnor.common.services.shared.validation.model.ValidationMessage;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.kie.workbench.common.screens.datamodeller.client.pdescriptor.ClassRow;
import org.kie.workbench.common.screens.datamodeller.client.pdescriptor.ClassRowImpl;
import org.kie.workbench.common.screens.datamodeller.client.pdescriptor.PersistenceUnitPropertyGrid;
import org.kie.workbench.common.screens.datamodeller.client.pdescriptor.ProjectClassList;
import org.kie.workbench.common.screens.datamodeller.client.type.PersistenceDescriptorType;
import org.kie.workbench.common.screens.datamodeller.client.widgets.datasourceselector.DataSourceSelector;
import org.kie.workbench.common.screens.datamodeller.model.persistence.PersistenceDescriptorEditorContent;
import org.kie.workbench.common.screens.datamodeller.model.persistence.PersistenceDescriptorModel;
import org.kie.workbench.common.screens.datamodeller.model.persistence.PersistenceUnitModel;
import org.kie.workbench.common.screens.datamodeller.model.persistence.TransactionType;
import org.kie.workbench.common.screens.datamodeller.service.DataModelerService;
import org.kie.workbench.common.screens.datamodeller.service.PersistenceDescriptorEditorService;
import org.kie.workbench.common.screens.datamodeller.service.PersistenceDescriptorService;
import org.kie.workbench.common.widgets.client.popups.validation.ValidationPopup;
import org.kie.workbench.common.widgets.client.resources.i18n.CommonConstants;
import org.kie.workbench.common.widgets.metadata.client.KieEditorWrapperView;
import org.kie.workbench.common.widgets.metadata.client.widget.OverviewWidgetPresenter;
import org.mockito.Mock;
import org.uberfire.backend.vfs.ObservablePath;
import org.uberfire.backend.vfs.Path;
import org.uberfire.ext.editor.commons.client.history.VersionRecordManager;
import org.uberfire.mocks.CallerMock;
import org.uberfire.mocks.EventSourceMock;
import org.uberfire.mvp.PlaceRequest;
import org.uberfire.workbench.events.NotificationEvent;

import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyList;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;

@RunWith( GwtMockitoTestRunner.class)
public class PersistenceDescriptorEditorPresenterTest {

    @GwtMock
    private PersistenceDescriptorType persistenceDescriptorType;

    @GwtMock
    private PersistenceDescriptorEditorView view;

    @GwtMock
    private PersistenceUnitPropertyGrid propertyGrid;

    @GwtMock
    private DataSourceSelector dataSourceSelector;

    @GwtMock
    private ProjectClassList projectClassList;

    @GwtMock
    private ObservablePath path;

    @GwtMock
    private VersionRecordManager _versionRecordManager;

    private PersistenceDescriptorEditorPresenter presenter;

    @Mock
    private ValidationPopup validationPopup;

    @Mock
    private PersistenceDescriptorEditorService editorService;

    @Mock
    private PersistenceDescriptorService descriptorService;

    @Mock
    private DataModelerService dataModelerService;

    @Mock
    private EventSourceMock<NotificationEvent> notificationEvent;

    @Before
    public void setup() {
        presenter = new PersistenceDescriptorEditorPresenter( view,
                                                              persistenceDescriptorType,
                                                              dataSourceSelector,
                                                              new CallerMock<>( editorService ),
                                                              new CallerMock<>( descriptorService ),
                                                              new CallerMock<>( dataModelerService ),
                                                              validationPopup
                                                                ) {
            {
                kieView = mock( KieEditorWrapperView.class );
                this.versionRecordManager = _versionRecordManager;
                overviewWidget = mock( OverviewWidgetPresenter.class );
                this.notification = notificationEvent;
            }

            protected void makeMenuBar() {

            }

            protected void addSourcePage() {

            }

        };
        verify( view, times( 1 ) ).setPresenter( presenter );
        when( editorService.loadContent( any( Path.class ), anyBoolean() ) ).thenReturn( createEditorContent() );
        when( dataModelerService.findPersistableClasses( any( Path.class ) ) ).thenReturn( createPersistableClasses() );
    }

    private void loadContent() {
        when( _versionRecordManager.getCurrentPath() ).thenReturn( path );
        when ( view.getPersistenceUnitProperties() ).thenReturn( propertyGrid );
        when ( view.getPersistenceUnitClasses() ).thenReturn( projectClassList );

        presenter.onStartup( path, mock( PlaceRequest.class ) );
    }

    @Test
    public void testOnLoad() {

        loadContent();

        verify( view, times( 1 ) ).setReadOnly( false );
        verify( view, times( 1 ) ).hideBusyIndicator();

        List<ClassRow> classRows = new ArrayList<ClassRow>();
        classRows.add( new ClassRowImpl( "Class1" ) );
        classRows.add( new ClassRowImpl( "Class2" ) );
        when( projectClassList.getClasses() ).thenReturn( classRows );

        assertEquals( "2.0", presenter.getContent().getDescriptorModel().getVersion() );
        assertEquals( "UnitName", presenter.getContent().getDescriptorModel().getPersistenceUnit().getName() );
        assertEquals( TransactionType.JTA, presenter.getContent().getDescriptorModel().getPersistenceUnit().getTransactionType() );
        assertEquals( "ProviderClass", presenter.getContent().getDescriptorModel().getPersistenceUnit().getProvider() );
        assertEquals( "JTADataSource", presenter.getContent().getDescriptorModel().getPersistenceUnit().getJtaDataSource() );
        assertEquals( 2, presenter.getContent().getDescriptorModel().getPersistenceUnit().getClasses().size() );
        assertEquals( "Class1", presenter.getContent().getDescriptorModel().getPersistenceUnit().getClasses().get( 0 ) );
        assertEquals( "Class2", presenter.getContent().getDescriptorModel().getPersistenceUnit().getClasses().get( 1 ) );
    }

    @Test
    public void onJTADataSourceChange( ) {

       loadContent();

        when( view.getJTADataSource() ).thenReturn( "NewJTADataSource" );
        presenter.onJTADataSourceChange();

        verify( view, times( 1 ) ).getJTADataSource();
        assertEquals( "NewJTADataSource", presenter.getContent().getDescriptorModel().getPersistenceUnit().getJtaDataSource() );
    }

    @Test
    public void testOnJTATransactionsChange() {

        loadContent();

        when( view.getJTATransactions() ).thenReturn( true );
        presenter.onJTATransactionsChange();

        verify( view, times( 1 ) ).getJTATransactions();
        assertEquals( TransactionType.JTA, presenter.getContent().getDescriptorModel().getPersistenceUnit().getTransactionType() );
    }

    @Test
    public void testOnResourceLocalTransactionsChange() {

        loadContent();

        when( view.getResourceLocalTransactions() ).thenReturn( true );
        presenter.onResourceLocalTransactionsChange();

        verify( view, times( 2 ) ).getResourceLocalTransactions();
        assertEquals( TransactionType.RESOURCE_LOCAL, presenter.getContent().getDescriptorModel().getPersistenceUnit().getTransactionType() );
    }

    @Test
    public void testOnPersistenceUnitNameChange() {

        loadContent();

        when( view.getPersistenceUnitName() ).thenReturn( "NewUnitName" );
        presenter.onPersistenceUnitNameChange();

        verify( view, times( 1 ) ).getPersistenceUnitName();
        assertEquals( "NewUnitName", presenter.getContent().getDescriptorModel().getPersistenceUnit().getName() );
    }

    @Test
    public void testOnPersistenceProviderChange() {

        loadContent();

        when( view.getPersistenceProvider() ).thenReturn( "NewPersistenceProvider" );
        presenter.onPersistenceProviderChange();

        verify( view, times( 1 ) ).getPersistenceProvider();
        assertEquals( "NewPersistenceProvider", presenter.getContent().getDescriptorModel().getPersistenceUnit().getProvider() );
    }

    @Test
    public void testOnLoadClasses() {

        loadContent();

        when( view.getPersistenceUnitClasses() ).thenReturn( projectClassList );

        List<ClassRow> classRows = new ArrayList<ClassRow>();
        classRows.add( new ClassRowImpl( "Class3" ) );
        classRows.add( new ClassRowImpl( "Class4") );
        when( projectClassList.getClasses() ).thenReturn( classRows );

        presenter.onLoadClasses();

        verify( view, times( 1 ) ).showBusyIndicator( anyString() );

        verify( view, times( 2 ) ).hideBusyIndicator();
        verify( view, times( 5 ) ).getPersistenceUnitClasses();

        assertEquals( 2, presenter.getContent().getDescriptorModel().getPersistenceUnit().getClasses().size() );
        assertEquals( classRows.get( 0 ).getClassName(), presenter.getContent().getDescriptorModel().getPersistenceUnit().getClasses().get( 0 ) );
        assertEquals( classRows.get( 1 ).getClassName(), presenter.getContent().getDescriptorModel().getPersistenceUnit().getClasses().get( 1 ) );
    }

    @Test
    public void testOnLoadClass() {

        loadContent();

        when( view.getPersistenceUnitClasses() ).thenReturn( projectClassList );

        List<ClassRow> classRows = new ArrayList<ClassRow>();
        classRows.add( new ClassRowImpl( "Class3" ) );
        classRows.add( new ClassRowImpl( "Class4" ) );
        projectClassList.setClasses( classRows );
        when( projectClassList.getClasses() ).thenReturn( classRows );
        when( dataModelerService.isPersistableClass( eq( "NewClass" ), any( Path.class ) ) ).thenReturn( true );

        presenter.onLoadClass( "NewClass" );
        classRows.add( new ClassRowImpl( "NewClass" ) );

        verify( view, times( 1 ) ).showBusyIndicator( anyString() );

        verify( view, times( 2 ) ).hideBusyIndicator();
        verify( view, times( 5 ) ).getPersistenceUnitClasses();
        verify( projectClassList, times( 1 ) ).setNewClassName( null );
        verify( projectClassList, times( 1 ) ).setNewClassHelpMessage( null );

        assertEquals( 3, presenter.getContent().getDescriptorModel().getPersistenceUnit().getClasses().size() );
        assertEquals( classRows.get( 0 ).getClassName(), presenter.getContent().getDescriptorModel().getPersistenceUnit().getClasses().get( 0 ) );
        assertEquals( classRows.get( 1 ).getClassName(), presenter.getContent().getDescriptorModel().getPersistenceUnit().getClasses().get( 1 ) );
        assertEquals( classRows.get( 2 ).getClassName(), "NewClass" );
    }

    @Test
    public void testOnValidateWithNoMessages() {
        loadContent();
        List<ValidationMessage> messages = new ArrayList<>(  );
        when( descriptorService.validate( path, presenter.getContent().getDescriptorModel() ) ).thenReturn( messages );
        presenter.onValidate().execute();
        verify( validationPopup, never() ).showTranslatedMessages( anyList() );
        verify( notificationEvent, times( 1 ) ).fire( new NotificationEvent(
                CommonConstants.INSTANCE.ItemValidatedSuccessfully( ),
                NotificationEvent.NotificationType.SUCCESS ) );
    }

    @Test
    public void testOnValidateWithMessages() {
        loadContent();
        List<ValidationMessage> messages = new ArrayList<>(  );
        messages.add( mock( ValidationMessage.class ) );
        messages.add( mock( ValidationMessage.class ) );

        when( descriptorService.validate( path, presenter.getContent().getDescriptorModel() ) ).thenReturn( messages );
        presenter.onValidate().execute();
        verify( validationPopup, times( 1 ) ).showTranslatedMessages( messages );
    }

    private PersistenceDescriptorEditorContent createEditorContent() {
        PersistenceDescriptorEditorContent content = new PersistenceDescriptorEditorContent();
        PersistenceDescriptorModel model = new PersistenceDescriptorModel();
        model.setVersion( "2.0" );
        PersistenceUnitModel unitModel = new PersistenceUnitModel();
        model.setPersistenceUnit( unitModel );

        unitModel.setName( "UnitName" );
        unitModel.setTransactionType( TransactionType.JTA );
        unitModel.setProvider( "ProviderClass" );
        unitModel.setJtaDataSource( "JTADataSource" );
        List<String> classes = new ArrayList<String>(  );
        classes.add( "Class1" );
        classes.add( "Class2" );
        unitModel.setClasses( classes );

        content.setDescriptorModel( model );
        content.setOverview( new Overview() );
        return content;
    }

    private List<String> createPersistableClasses() {
        List<String> classes = new ArrayList<String>();
        classes.add( "Class3" );
        classes.add( "Class4" );
        return classes;
    }
}