text:
//   Copyright 2011 Microsoft Corporation
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

namespace Microsoft.Data.OData
{
    #region Namespaces
    using System;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.IO;
    using System.Text;
    using System.Xml;
#if ODATALIB_ASYNC
    using System.Threading.Tasks;
#endif
    using Microsoft.Data.Edm;
    using Microsoft.Data.Edm.Csdl;
    using Microsoft.Data.Edm.Library;
    using Microsoft.Data.OData.Atom;
    using Microsoft.Data.OData.Metadata;
    using Microsoft.Data.OData.Json;
    #endregion Namespaces

    ///
    /// Writer class used to write all OData payloads (entries, feeds, metadata documents, service documents, etc.).
    ///
    public sealed class ODataMessageWriter : IDisposable
    {
        /// The message for which the message writer was created.
        private readonly ODataMessage message;

        /// A flag indicating whether we are writing a request or a response message.
        private readonly bool writingResponse;

        /// The message writer settings to use when writing the message payload.
        private readonly ODataMessageWriterSettings settings;

        /// The model. Non-null if we do have metadata available.
        private readonly IEdmModel model;

        /// The optional URL resolver to perform custom URL resolution for URLs written to the payload.
        private readonly IODataUrlResolver urlResolver;

        /// Flag to ensure that only a single write method is called on the message writer.
        private bool writeMethodCalled;

        /// True if Dispose() has been called on this message writer, False otherwise.
        private bool isDisposed;

        /// The output context we're using to write the payload.
        /// <remarks>This is null until the first write operation is called.</remarks>
        private ODataOutputContext outputContext;

        /// The payload kind of the payload to be written with this writer.
        /// <remarks>This is either set via the SetHeadersForPayload method or implicitly when one of the write (or writer creation) methods is called.</remarks>
        private ODataPayloadKind writerPayloadKind = ODataPayloadKind.Unsupported;

        /// The <see cref="ODataFormat"/> of the payload to be written with this writer.
        /// <remarks>This is either set via the SetHeadersForPayload method or implicitly when one of the write (or writer creation) methods is called.</remarks>
        private ODataFormat format;

        /// The <see cref="Encoding"/> of the payload to be written with this writer.
        /// <remarks>This is either set via the SetHeadersForPayload method or implicitly when one of the write (or writer creation) methods is called.</remarks>
        private Encoding encoding;

        /// The batch boundary string if the payload to be written is a batch request or response.
        /// <remarks>This is either set via the SetHeadersForPayload method or implicitly when the CreateBatchWriter method is called.</remarks>
        private string batchBoundary;

        /// Flag to prevent writing more than one error to the payload.
        private bool writeErrorCalled;

        ///
        /// Creates a new ODataMessageWriter for the given request message.
        ///
        /// <param name="requestMessage">The request message for which to create the writer.</param>
        public ODataMessageWriter(IODataRequestMessage requestMessage)
            : this(requestMessage, null)
        {
        }

        ///
        /// Creates a new ODataMessageWriter for the given request message and message writer settings.
        ///
        /// <param name="requestMessage">The request message for which to create the writer.</param>
        /// <param name="settings">The message writer settings to use for writing the message payload.</param>
        public ODataMessageWriter(IODataRequestMessage requestMessage, ODataMessageWriterSettings settings)
            : this(requestMessage, settings, null)
        {
        }

        ///
        /// Creates a new ODataMessageWriter for the given request message and message writer settings.
        ///
        /// <param name="requestMessage">The request message for which to create the writer.</param>
        /// <param name="settings">The message writer settings to use for writing the message payload.</param>
        /// <param name="model">The model to use.</param>
        public ODataMessageWriter(IODataRequestMessage requestMessage, ODataMessageWriterSettings settings, IEdmModel model)
        {
            ExceptionUtils.CheckArgumentNotNull(requestMessage, "requestMessage");

            // Clone the settings here so we can later modify them without changing the settings passed to us by the user
            this.settings = settings == null ? new ODataMessageWriterSettings() : new ODataMessageWriterSettings(settings);
            WriterValidationUtils.ValidateMessageWriterSettings(this.settings);

            this.writingResponse = false;
            this.message = new ODataRequestMessage(requestMessage, /*writing*/ true, this.settings.DisableMessageStreamDisposal, /*maxMessageSize*/ -1);
            this.urlResolver = requestMessage as IODataUrlResolver;
            this.model = model ?? EdmCoreModel.Instance;
        }

        ///
        /// Creates a new ODataMessageWriter for the given response message.
        ///
        /// <param name="responseMessage">The response message for which to create the writer.</param>
        public ODataMessageWriter(IODataResponseMessage responseMessage)
            : this(responseMessage, null)
        {
        }

        ///
        /// Creates a new ODataMessageWriter for the given response message and message writer settings.
        ///
        /// <param name="responseMessage">The response message for which to create the writer.</param>
        /// <param name="settings">The message writer settings to use for writing the message payload.</param>
        public ODataMessageWriter(IODataResponseMessage responseMessage, ODataMessageWriterSettings settings)
            : this(responseMessage, settings, null)
        {
        }

        ///
        /// Creates a new ODataMessageWriter for the given response message and message writer settings.
        ///
        /// <param name="responseMessage">The response message for which to create the writer.</param>
        /// <param name="settings">The message writer settings to use for writing the message payload.</param>
        /// <param name="model">The model to use.</param>
        public ODataMessageWriter(IODataResponseMessage responseMessage, ODataMessageWriterSettings settings, IEdmModel model)
        {
            ExceptionUtils.CheckArgumentNotNull(responseMessage, "responseMessage");

            // Clone the settings here so we can later modify them without changing the settings passed to us by the user
            this.settings = settings == null ? new ODataMessageWriterSettings() : new ODataMessageWriterSettings(settings);
            WriterValidationUtils.ValidateMessageWriterSettings(this.settings);

            this.writingResponse = true;
            this.message = new ODataResponseMessage(responseMessage, /*writing*/ true, this.settings.DisableMessageStreamDisposal, /*maxMessageSize*/ -1);
            this.urlResolver = responseMessage as IODataUrlResolver;
            this.model = model ?? EdmCoreModel.Instance;
        }

        ///
        /// Creates an <see cref="ODataWriter" /> to write a feed.
        ///
        /// <returns>The created writer.</returns>
        public ODataWriter CreateODataFeedWriter()
        {
            this.VerifyCanCreateODataFeedWriter();
            return this.WriteToOutput(
                ODataPayloadKind.Feed,
                null /* verifyHeaders */,
                (context) => context.CreateODataFeedWriter());
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously creates an <see cref="ODataWriter" /> to write a feed.
        ///
        /// <returns>A running task for the created writer.</returns>
        public Task<ODataWriter> CreateODataFeedWriterAsync()
        {
            this.VerifyCanCreateODataFeedWriter();
            return this.WriteToOutputAsync(
                ODataPayloadKind.Feed,
                null /* verifyHeaders */,
                (context) => context.CreateODataFeedWriterAsync());
        }
#endif

        ///
        /// Creates an <see cref="ODataWriter" /> to write an entry.
        ///
        /// <returns>The created writer.</returns>
        public ODataWriter CreateODataEntryWriter()
        {
            this.VerifyCanCreateODataEntryWriter();
            return this.WriteToOutput(
                ODataPayloadKind.Entry,
                null /* verifyHeaders */,
                (context) => context.CreateODataEntryWriter());
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously creates an <see cref="ODataWriter" /> to write an entry.
        ///
        /// <returns>A running task for the created writer.</returns>
        public Task<ODataWriter> CreateODataEntryWriterAsync()
        {
            this.VerifyCanCreateODataEntryWriter();
            return this.WriteToOutputAsync(
                ODataPayloadKind.Entry,
                null /* verifyHeaders */,
                (context) => context.CreateODataEntryWriterAsync());
        }
#endif

        ///
        /// Creates an <see cref="ODataCollectionWriter" /> to write a collection of primitive or complex values (as result of a service operation invocation).
        ///
        /// <returns>The created collection writer.</returns>
        public ODataCollectionWriter CreateODataCollectionWriter()
        {
            this.VerifyCanCreateODataCollectionWriter();
            return this.WriteToOutput(
                ODataPayloadKind.Collection,
                null /* verifyHeaders */,
                (context) => context.CreateODataCollectionWriter());
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously creates an <see cref="ODataCollectionWriter" /> to write a collection of primitive or complex values (as result of a service operation invocation).
        ///
        /// <returns>A running task for the created collection writer.</returns>
        public Task<ODataCollectionWriter> CreateODataCollectionWriterAsync()
        {
            this.VerifyCanCreateODataCollectionWriter();
            return this.WriteToOutputAsync(
                ODataPayloadKind.Collection,
                null /* verifyHeaders */,
                (context) => context.CreateODataCollectionWriterAsync());
        }
#endif

        ///
        /// Creates an <see cref="ODataBatchWriter" /> to write a batch of requests or responses.
        ///
        /// <returns>The created batch writer.</returns>
        public ODataBatchWriter CreateODataBatchWriter()
        {
            this.VerifyCanCreateODataBatchWriter();
            return this.WriteToOutput(
                ODataPayloadKind.Batch,
                null /* verifyHeaders */,
                (context) => context.CreateODataBatchWriter(this.batchBoundary));
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously creates an <see cref="ODataBatchWriter" /> to write a batch of requests or responses.
        ///
        /// <returns>A running task for the created batch writer.</returns>
        public Task<ODataBatchWriter> CreateODataBatchWriterAsync()
        {
            this.VerifyCanCreateODataBatchWriter();
            return this.WriteToOutputAsync(
                ODataPayloadKind.Batch,
                null /* verifyHeaders */,
                (context) => context.CreateODataBatchWriterAsync(this.batchBoundary));
        }
#endif

        ///
        /// Creates an <see cref="ODataParameterWriter" /> to write a parameter payload.
        ///
        /// <param name="functionImport">The function import whose parameters will be written.</param>
        /// <returns>The created parameter writer.</returns>
        public ODataParameterWriter CreateODataParameterWriter(IEdmFunctionImport functionImport)
        {
            this.VerifyCanCreateODataParameterWriter(functionImport);
            return this.WriteToOutput(
                ODataPayloadKind.Parameter,
                this.VerifyODataParameterWriterHeaders,
                (context) => context.CreateODataParameterWriter(functionImport));
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously creates an <see cref="ODataParameterWriter" /> to write a parameter payload.
        ///
        /// <param name="functionImport">The function import whose parameters will be written.</param>
        /// <returns>A running task for the created parameter writer.</returns>
        public Task<ODataParameterWriter> CreateODataParameterWriterAsync(IEdmFunctionImport functionImport)
        {
            this.VerifyCanCreateODataParameterWriter(functionImport);
            return this.WriteToOutputAsync(
                ODataPayloadKind.Parameter,
                this.VerifyODataParameterWriterHeaders,
                (context) => context.CreateODataParameterWriterAsync(functionImport));
        }
#endif

        ///
        /// Writes a service document with the specified <paramref name="defaultWorkspace"/>
        /// as message payload.
        ///
        /// <param name="defaultWorkspace">The default workspace to write in the service document.</param>
        public void WriteServiceDocument(ODataWorkspace defaultWorkspace)
        {
            this.VerifyCanWriteServiceDocument(defaultWorkspace);
            this.WriteToOutput(
                ODataPayloadKind.ServiceDocument,
                null /* verifyHeaders */,
                (context) => context.WriteServiceDocument(defaultWorkspace));
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously writes a service document with the specified <paramref name="defaultWorkspace"/>
        /// as message payload.
        ///
        /// <param name="defaultWorkspace">The default workspace to write in the service document.</param>
        /// <returns>A task representing the asynchronous operation of writing the service document.</returns>
        public Task WriteServiceDocumentAsync(ODataWorkspace defaultWorkspace)
        {
            this.VerifyCanWriteServiceDocument(defaultWorkspace);
            return this.WriteToOutputAsync(
                ODataPayloadKind.ServiceDocument,
                null /* verifyHeaders */,
                (context) => context.WriteServiceDocumentAsync(defaultWorkspace));
        }
#endif

        ///
        /// Writes an <see cref="ODataProperty"/> as message payload.
        ///
        /// <param name="property">The property to write.</param>
        public void WriteProperty(ODataProperty property)
        {
            this.VerifyCanWriteProperty(property);
            this.WriteToOutput(
                ODataPayloadKind.Property,
                null /* verifyHeaders */,
                (context) => context.WriteProperty(property));
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously writes an <see cref="ODataProperty"/> as message payload.
        ///
        /// <param name="property">The property to write</param>
        /// <returns>A task representing the asynchronous operation of writing the property.</returns>
        public Task WritePropertyAsync(ODataProperty property)
        {
            this.VerifyCanWriteProperty(property);
            return this.WriteToOutputAsync(
                ODataPayloadKind.Property,
                null /* verifyHeaders */,
                (context) => context.WritePropertyAsync(property));
        }
#endif

        ///
        /// Writes an <see cref="ODataError"/> as the message payload.
        ///
        /// <param name="error">The error to write.</param>
        /// <param name="includeDebugInformation">
        /// A flag indicating whether debug information (e.g., the inner error from the <paramref name="error"/>) should
        /// be included in the payload. This should only be used in debug scenarios.
        /// </param>
        public void WriteError(ODataError error, bool includeDebugInformation)
        {
            // We currently assume that the error is top-level if no create/write method has been called on this message writer.
            // It is possible that the user would create a Json writer, but writes nothing to it before writes the first error.
            // For example it is valid to call CreateEntryWriter() and then WriteError(). In that case the Json payload would
            // contain just an error without the Json wrapper.
            if (this.outputContext == null)
            {
                // Top-level error
                this.VerifyCanWriteTopLevelError(error);
                this.WriteToOutput(
                    ODataPayloadKind.Error,
                    null /* verifyHeaders */,
                    (context) => context.WriteError(error, includeDebugInformation));
                return;
            }

            // In-stream error
            this.VerifyCanWriteInStreamError(error);
            this.outputContext.WriteInStreamError(error, includeDebugInformation);
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously writes an <see cref="ODataError"/> as the message payload.
        ///
        /// <param name="error">The error to write.</param>
        /// <param name="includeDebugInformation">
        /// A flag indicating whether debug information (e.g., the inner error from the <paramref name="error"/>) should
        /// be included in the payload. This should only be used in debug scenarios.
        /// </param>
        /// <returns>A task representing the asynchronous operation of writing the error.</returns>
        public Task WriteErrorAsync(ODataError error, bool includeDebugInformation)
        {
            // We currently assume that the error is top-level if no create/write method has been called on this message writer.
            // It is possible that the user would create a Json writer, but writes nothing to it before writes the first error.
            // For example it is valid to call CreateEntryWriter() and then WriteError(). In that case the Json payload would
            // contain just an error without the Json wrapper.
            if (this.outputContext == null)
            {
                // Top-level error
                this.VerifyCanWriteTopLevelError(error);
                return this.WriteToOutputAsync(
                    ODataPayloadKind.Error,
                    null /* verifyHeaders */,
                    (context) => context.WriteErrorAsync(error, includeDebugInformation));
            }

            // In-stream error
            this.VerifyCanWriteInStreamError(error);
            return this.outputContext.WriteInStreamErrorAsync(error, includeDebugInformation);
        }
#endif

        ///
        /// Writes the result of a $links query as the message payload.
        ///
        /// <param name="links">The entity reference links to write as message payload.</param>
        public void WriteEntityReferenceLinks(ODataEntityReferenceLinks links)
        {
            this.VerifyCanWriteEntityReferenceLinks(links);
            this.WriteToOutput(
                ODataPayloadKind.EntityReferenceLinks,
                () => this.VerifyEntityReferenceLinksHeaders(links),
                (context) => context.WriteEntityReferenceLinks(links));
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously writes the result of a $links query as the message payload.
        ///
        /// <param name="links">The entity reference links to write as message payload.</param>
        /// <returns>A task representing the asynchronous writing of the entity reference links.</returns>
        public Task WriteEntityReferenceLinksAsync(ODataEntityReferenceLinks links)
        {
            this.VerifyCanWriteEntityReferenceLinks(links);
            return this.WriteToOutputAsync(
                ODataPayloadKind.EntityReferenceLinks,
                () => this.VerifyEntityReferenceLinksHeaders(links),
                (context) => context.WriteEntityReferenceLinksAsync(links));
        }
#endif

        ///
        /// Writes a singleton result of a $links query as the message payload.
        ///
        /// <param name="link">The entity reference link to write as message payload.</param>
        public void WriteEntityReferenceLink(ODataEntityReferenceLink link)
        {
            this.VerifyCanWriteEntityReferenceLink(link);
            this.WriteToOutput(
                ODataPayloadKind.EntityReferenceLink,
                null /* verifyHeaders */,
                (context) => context.WriteEntityReferenceLink(link));
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously writes a singleton result of a $links query as the message payload.
        ///
        /// <param name="link">The link result to write as message payload.</param>
        /// <returns>A running task representing the writing of the link.</returns>
        public Task WriteEntityReferenceLinkAsync(ODataEntityReferenceLink link)
        {
            this.VerifyCanWriteEntityReferenceLink(link);
            return this.WriteToOutputAsync(
                ODataPayloadKind.EntityReferenceLink,
                null /* verifyHeaders */,
                (context) => context.WriteEntityReferenceLinkAsync(link));
        }
#endif

        ///
        /// Writes a single value as the message body.
        ///
        /// <param name="value">The value to write.</param>
        public void WriteValue(object value)
        {
            ODataPayloadKind payloadKind = this.VerifyCanWriteValue(value);
            this.WriteToOutput(
                payloadKind,
                null /* verifyHeaders */,
                (context) => context.WriteValue(value));
        }

#if ODATALIB_ASYNC
        ///
        /// Asynchronously writes a single value as the message body.
        ///
        /// <param name="value">The value to write.</param>
        /// <returns>A running task representing the writing of the value.</returns>
        public Task WriteValueAsync(object value)
        {
            ODataPayloadKind payloadKind = this.VerifyCanWriteValue(value);
            return this.WriteToOutputAsync(
                payloadKind,
                null /* verifyHeaders */,
                (context) => context.WriteValueAsync(value));
        }
#endif

        ///
        /// Writes the metadata document as the message body.
        ///
        public void WriteMetadataDocument()
        {
            this.VerifyCanWriteMetadataDocument();
            this.WriteToOutput(
                ODataPayloadKind.MetadataDocument,
                this.VerifyMetadataDocumentHeaders,
                (context) => context.WriteMetadataDocument());
        }

        ///
        /// IDisposable.Dispose() implementation to cleanup unmanaged resources of the writer.
        ///
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        ///
        /// Sets the content-type and data service version headers on the message used by the message writer.
        /// This method can be called if it is important to set all the message headers before calling any of the
        /// write (or writer creation) methods on the <see cref="ODataMessageWriter"/>.
        /// If it is sufficient to set the headers when the write (or writer creation) methods on the <see cref="ODataMessageWriter"/>
        /// are called, you don't have to call this method and setting the headers will happen automatically.
        ///
        /// <param name="payloadKind">The kind of payload to be written with this message writer.</param>
        /// <returns>The <see cref="ODataFormat"/> used for the specified <paramref name="payloadKind"/>.</returns>
        internal ODataFormat SetHeaders(ODataPayloadKind payloadKind)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(payloadKind != ODataPayloadKind.Unsupported, "payloadKind != ODataPayloadKind.Unsupported");

            this.writerPayloadKind = payloadKind;

            // Make sure we have a version set on the message writer settings; if none was specified on the settings, try to read
            // it from the message headers. If not specified in the headers either, fall back to a default.
            // NOTE: This method will potentially also set the data service version header.
            this.EnsureODataVersion();
            Debug.Assert(this.settings.Version.HasValue, "ODataVersion must have been set by now.");

            // Make sure we have a content-type and compute the format from the settings and/or the message headers.
            // NOTE: This method will potentially also set the content type header.
            this.EnsureODataFormatAndContentType();
            return this.format;
        }

        ///
        /// If no headers have been set, sets the content-type and data service version headers on the message used by the message writer.
        /// If headers have been set explicitly (via ODataUtils.SetHeaderForPayload) this method verifies that the payload kind used to
        /// create the headers is the same as the one being passed in <paramref name="payloadKind"/>.
        ///
        /// <param name="payloadKind">The kind of payload to be written with this message writer.</param>
        private void SetOrVerifyHeaders(ODataPayloadKind payloadKind)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(payloadKind != ODataPayloadKind.Unsupported, "payloadKind != ODataPayloadKind.Unsupported");

            // verify that no payload kind has been set or that the payload kind set previously and the
            // payload that is attempted to being written are the same
            this.VerifyPayloadKind(payloadKind);

            if (this.writerPayloadKind == ODataPayloadKind.Unsupported)
            {
                // no payload kind or headers have been set; set them now
                this.SetHeaders(payloadKind);
            }
        }

        ///
        /// Ensures that the version of the OData protocol is set.
        ///
        /// <remarks>
        /// If a version is specified explicitly on the writer settings, it is used.
        /// Otherwise the method tries to read the version from the message headers.
        /// If there is a version header but the value cannot be parsed, we fail.
        /// If there is no version header, we fall back to the default version.
        /// </remarks>
        private void EnsureODataVersion()
        {
            // if no version was specified in the user settings, try to read it from the message headers
            if (!this.settings.Version.HasValue)
            {
                // Read the version header and parse it; fail if we can't parse it.
                // Fall back to a default if we don't find a version header.
                this.settings.Version = ODataUtilsInternal.GetDataServiceVersion(this.message, ODataConstants.ODataDefaultProtocolVersion);
                Debug.Assert(this.settings.Version.HasValue, "The version must have been set by now.");
            }
            else
            {
                // Set the data service version
                ODataUtilsInternal.SetDataServiceVersion(this.message, this.settings);
            }

            // If the version is set to >= 3.0 we must not have a format behavior other than the default behavior.
            // Custom format behaviors for the WCF DS client and server are only supported in versions < 3.0
            if (this.settings.Version >= ODataVersion.V3 && this.settings.WriterBehavior.FormatBehaviorKind != ODataBehaviorKind.Default)
            {
                this.settings.WriterBehavior.UseDefaultFormatBehavior();
            }
        }

        ///
        /// Ensures that the OData format is computed and set; if needed, sets the content type
        /// header of the message.
        ///
        /// <remarks>
        /// This method computes and ensures that a content type exists and computes the
        /// OData format from it. If a content type is explicitly specified through
        /// <see cref="Microsoft.Data.OData.ODataUtils.SetHeadersForPayload(Microsoft.Data.OData.ODataMessageWriter, Microsoft.Data.OData.ODataPayloadKind)"/>
        /// or <see cref="Microsoft.Data.OData.ODataMessageWriterSettings.SetContentType(string, string)"/> it will be used. If no
        /// content type is specified in either place, the message headers are checked for
        /// a content type header.
        /// If the content type is computed from settings, the content type header is set on the message.
        /// </remarks>
        private void EnsureODataFormatAndContentType()
        {
            Debug.Assert(this.writerPayloadKind != ODataPayloadKind.Unsupported, "Writer payload kind should have been set by now.");

            string contentType = null;

            // If neither format nor accept headers were specified in the writer settings, try to read the content type from the message headers.
            if (!this.settings.UseFormat.HasValue)
            {
                contentType = this.message.GetHeader(ODataConstants.ContentTypeHeader);
                contentType = contentType == null ? null : contentType.Trim();
            }

            // If we found a content type header, use it. Otherwise use the default behavior.
            if (!string.IsNullOrEmpty(contentType))
            {
                ODataPayloadKind computedPayloadKind;
                MediaType mediaType;
                this.format = MediaTypeUtils.GetFormatFromContentType(contentType, new ODataPayloadKind[] { this.writerPayloadKind }, MediaTypeResolver.DefaultMediaTypeResolver, out mediaType, out this.encoding, out computedPayloadKind, out this.batchBoundary);
                Debug.Assert(this.writerPayloadKind == computedPayloadKind, "The payload kinds must always match.");
            }
            else
            {
                // Determine the content type and format from the settings. Note that if neither format nor accept headers have been specified in the settings
                // we fall back to a default (of null accept headers).
                MediaType mediaType;
                this.format = MediaTypeUtils.GetContentTypeFromSettings(this.settings, this.writerPayloadKind, MediaTypeResolver.DefaultMediaTypeResolver, out mediaType, out this.encoding);

                if (this.writerPayloadKind == ODataPayloadKind.Batch)
                {
                    // Note that this serves as verification only for now, since we only support a single content type and format for $batch payloads.
                    Debug.Assert(this.format == ODataFormat.Batch, "$batch should only support batch format since it's format independent.");
                    Debug.Assert(mediaType.FullTypeName == MimeConstants.MimeMultipartMixed, "$batch content type is currently only supported to be multipart/mixed.");

                    this.batchBoundary = ODataBatchWriterUtils.CreateBatchBoundary(this.writingResponse);

                    // Set the content type header here since all headers have to be set before getting the stream
                    // Note that the mediaType may have additional parameters, which we ignore here (intentional as per MIME spec).
                    // Note that we always generate a new boundary string here, even if the accept header contained one.
                    // We need the boundary to be as unique as possible to avoid possible collision with content of the batch operation payload.
                    // Our boundary string are generated to fulfill this requirement, client specified ones might not which might lead to wrong responses
                    // and at least in theory security issues.
                    contentType = ODataBatchWriterUtils.CreateMultipartMixedContentType(this.batchBoundary);
                }
                else
                {
                    this.batchBoundary = null;

                    // Compute the content type (incl. charset) and set the Content-Type header on the response message
                    contentType = HttpUtils.BuildContentType(mediaType, this.encoding);
                }

                // NOTE: set the content type header here since all headers have to be set before getting the stream
                this.message.SetHeader(ODataConstants.ContentTypeHeader, contentType);
            }
        }

        ///
        /// Verifies that feed writer can be created.
        ///
        private void VerifyCanCreateODataFeedWriter()
        {
            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies that entry writer can be created.
        ///
        private void VerifyCanCreateODataEntryWriter()
        {
            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies that collection writer can be created.
        ///
        private void VerifyCanCreateODataCollectionWriter()
        {
            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies that batch writer can be created.
        ///
        private void VerifyCanCreateODataBatchWriter()
        {
            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies that parameter writer can be created.
        ///
        /// <param name="functionImport">The function import whose parameters will be written.</param>
        private void VerifyCanCreateODataParameterWriter(IEdmFunctionImport functionImport)
        {
            if (this.writingResponse)
            {
                throw new ODataException(Strings.ODataParameterWriter_CannotCreateParameterWriterOnResponseMessage);
            }

            if (functionImport != null)
            {
                // check that we have a user model
                if (!this.model.IsUserModel())
                {
                    throw new ODataException(Strings.ODataMessageWriter_CannotSpecifyFunctionImportWithoutModel);
                }
            }

            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies headers for parameter payload.
        ///
        private void VerifyODataParameterWriterHeaders()
        {
            ODataVersionChecker.CheckParameterPayload(this.settings.Version.Value);
        }

        ///
        /// Verifies that service document can be written.
        ///
        /// <param name="defaultWorkspace">The default workspace to write.</param>
        private void VerifyCanWriteServiceDocument(ODataWorkspace defaultWorkspace)
        {
            ExceptionUtils.CheckArgumentNotNull(defaultWorkspace, "defaultWorkspace");

            if (!this.writingResponse)
            {
                throw new ODataException(Strings.ODataMessageWriter_ServiceDocumentInRequest);
            }

            // VerifyWriterNotDisposedAndNotUsed changes the state of the message writer, it should be called after
            // we check the error conditions above.
            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies that property can be written.
        ///
        /// <param name="property">The property to write.</param>
        private void VerifyCanWriteProperty(ODataProperty property)
        {
            ExceptionUtils.CheckArgumentNotNull(property, "property");

            if (property.Value is ODataStreamReferenceValue)
            {
                throw new ODataException(Strings.ODataMessageWriter_CannotWriteStreamPropertyAsTopLevelProperty(property.Name));
            }

            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies that top-level error can be written.
        ///
        /// <param name="error">The error to write.</param>
        private void VerifyCanWriteTopLevelError(ODataError error)
        {
            ExceptionUtils.CheckArgumentNotNull(error, "error");

            if (!this.writingResponse)
            {
                // errors can only be written for response messages
                throw new ODataException(Strings.ODataMessageWriter_ErrorPayloadInRequest);
            }

            // Note that this verifies that the writer is only used once, so it also verifies that
            // there's nothing written before the error.
            this.VerifyWriterNotDisposedAndNotUsed();

            // Mark it as error written so that we don't allow writing in-stream errors after this.
            this.writeErrorCalled = true;
        }

        ///
        /// Verifies that in-stream error can be written.
        ///
        /// <param name="error">The error to write.</param>
        private void VerifyCanWriteInStreamError(ODataError error)
        {
            ExceptionUtils.CheckArgumentNotNull(error, "error");

            this.VerifyNotDisposed();

            if (!this.writingResponse)
            {
                // errors can only be written for response messages
                throw new ODataException(Strings.ODataMessageWriter_ErrorPayloadInRequest);
            }

            if (this.writeErrorCalled)
            {
                throw new ODataException(Strings.ODataMessageWriter_WriteErrorAlreadyCalled);
            }

            this.writeErrorCalled = true;

            // Need to mark the writer as already used, so that we don't allow any other calls to it.
            this.writeMethodCalled = true;
        }

        ///
        /// Verifies that entity reference links can be written.
        ///
        /// <param name="links">The entity reference links to write as message payload.</param>
        private void VerifyCanWriteEntityReferenceLinks(ODataEntityReferenceLinks links)
        {
            // NOTE: we decided to not stream links for now but only make writing them async.
            ExceptionUtils.CheckArgumentNotNull(links, "links");

            if (!this.writingResponse)
            {
                throw new ODataException(Strings.ODataMessageWriter_EntityReferenceLinksInRequestNotAllowed);
            }

            // VerifyWriterNotDisposedAndNotUsed changes the state of the message writer, it should be called after
            // we check the error conditions above.
            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies headers for entity reference links.
        ///
        /// <param name="links">The entity reference links to write as message payload.</param>
        private void VerifyEntityReferenceLinksHeaders(ODataEntityReferenceLinks links)
        {
            Debug.Assert(this.settings != null && this.settings.Version.HasValue, "Settings must have been created and the version set.");

            if (links.Count.HasValue)
            {
                ODataVersionChecker.CheckCount(this.settings.Version.Value);
            }

            if (links.NextPageLink != null)
            {
                ODataVersionChecker.CheckNextLink(this.settings.Version.Value);
            }
        }

        ///
        /// Verifies that entity reference link can be written.
        ///
        /// <param name="link">The link result to write as message payload.</param>
        private void VerifyCanWriteEntityReferenceLink(ODataEntityReferenceLink link)
        {
            ExceptionUtils.CheckArgumentNotNull(link, "link");

            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies that value can be written.
        ///
        /// <param name="value">The value to write.</param>
        /// <returns>The payload kind to use when writing this value.</returns>
        private ODataPayloadKind VerifyCanWriteValue(object value)
        {
            if (value == null)
            {
                throw new ODataException(Strings.ODataMessageWriter_CannotWriteNullInRawFormat);
            }

            this.VerifyWriterNotDisposedAndNotUsed();

            // We cannot use AtomValueUtils.TryConvertPrimitiveToString for all cases since binary values are
            // converted into unencoded byte streams in the raw format
            // (as opposed to base64 encoded byte streams in the AtomValueUtils); see OIPI 2.2.6.4.1.
            return value is byte[] ? ODataPayloadKind.BinaryValue : ODataPayloadKind.Value;
        }

        ///
        /// Verifies that metadata document can be written.
        ///
        private void VerifyCanWriteMetadataDocument()
        {
            if (!this.writingResponse)
            {
                throw new ODataException(Strings.ODataMessageWriter_MetadataDocumentInRequest);
            }

            // check that we have a user model
            if (!this.model.IsUserModel())
            {
                throw new ODataException(Strings.ODataMessageWriter_CannotWriteMetadataWithoutModel);
            }

            // VerifyWriterNotDisposedAndNotUsed changes the state of the message writer, it should be called after
            // we check the error conditions above.
            this.VerifyWriterNotDisposedAndNotUsed();
        }

        ///
        /// Verifies headers for metadata document.
        ///
        private void VerifyMetadataDocumentHeaders()
        {
            // set the data service version on the model (if not already present)
            Version dataServiceVersion = this.model.GetDataServiceVersion();
            if (dataServiceVersion == null)
            {
                dataServiceVersion = this.settings.Version.Value.ToDataServiceVersion();
                this.model.SetDataServiceVersion(dataServiceVersion);
            }
        }

        ///
        /// Verifies that the ODataMessageWriter has not been disposed and has not been used before. An ODataMessageWriter
        /// can only be used to write a single message payload but can't be reused later except for writing an in-stream error.
        ///
        private void VerifyWriterNotDisposedAndNotUsed()
        {
            this.VerifyNotDisposed();
            if (this.writeMethodCalled)
            {
                throw new ODataException(Strings.ODataMessageWriter_WriterAlreadyUsed);
            }

            this.writeMethodCalled = true;
        }

        ///
        /// Check if the object has been disposed. Throws an ObjectDisposedException if the object has already been disposed.
        ///
        private void VerifyNotDisposed()
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
        }

        ///
        /// Perform the actual cleanup work.
        ///
        /// <param name="disposing">If 'true' this method is called from user code; if 'false' it is called by the runtime.</param>
        private void Dispose(bool disposing)
        {
            this.isDisposed = true;
            if (disposing)
            {
                try
                {
                    if (this.outputContext != null)
                    {
                        this.outputContext.Dispose();
                    }
                }
                finally
                {
                    this.outputContext = null;
                }
            }
        }

        ///
        /// Verifies that, if a payload kind has been set via SetHeaders, the payload kind that
        /// is being written is the same.
        ///
        /// <param name="payloadKindToWrite">The payload kind that is attempted to write.</param>
        private void VerifyPayloadKind(ODataPayloadKind payloadKindToWrite)
        {
            Debug.Assert(payloadKindToWrite != ODataPayloadKind.Unsupported, "payloadKindToWrite != ODataPayloadKind.Unsupported");

            if (this.writerPayloadKind != ODataPayloadKind.Unsupported && this.writerPayloadKind != payloadKindToWrite)
            {
                // if a payload kind has been set via SetHeaders that is not the same as the payload kind
                // that is attempted to write, we fail.
                throw new ODataException(Strings.ODataMessageWriter_IncompatiblePayloadKinds(this.writerPayloadKind, payloadKindToWrite));
            }
        }

        ///
        /// Creates an output context and invokes a write operation on it.
        ///
        /// <param name="payloadKind">The payload kind to write.</param>
        /// <param name="verifyHeaders">Optional action which will be called after the headers has been verified to perform payload specific verification.</param>
        /// <param name="writeAction">The write operation to invoke on the output.</param>
        private void WriteToOutput(ODataPayloadKind payloadKind, Action verifyHeaders, Action<ODataOutputContext> writeAction)
        {
            // Set the content type header here since all headers have to be set before getting the stream
            this.SetOrVerifyHeaders(payloadKind);

            if (verifyHeaders != null)
            {
                verifyHeaders();
            }

            // Create the output context
            this.outputContext = ODataOutputContext.CreateOutputContext(
                this.format,
                this.message,
                this.encoding,
                this.settings,
                this.writingResponse,
                this.model,
                this.urlResolver);
            writeAction(this.outputContext);
        }

        ///
        /// Creates an output context and invokes a write operation on it.
        ///
        /// <typeparam name="TResult">The type of the result of the write operation.</typeparam>
        /// <param name="payloadKind">The payload kind to write.</param>
        /// <param name="verifyHeaders">Optional action which will be called after the headers has been verified to perform payload specific verification.</param>
        /// <param name="writeFunc">The write operation to invoke on the output.</param>
        /// <returns>The result of the write operation.</returns>
        private TResult WriteToOutput<TResult>(ODataPayloadKind payloadKind, Action verifyHeaders, Func<ODataOutputContext, TResult> writeFunc)
        {
            // Set the content type header here since all headers have to be set before getting the stream
            this.SetOrVerifyHeaders(payloadKind);

            if (verifyHeaders != null)
            {
                verifyHeaders();
            }

            // Create the output context
            this.outputContext = ODataOutputContext.CreateOutputContext(
                this.format,
                this.message,
                this.encoding,
                this.settings,
                this.writingResponse,
                this.model,
                this.urlResolver);
            return writeFunc(this.outputContext);
        }

#if ODATALIB_ASYNC
        ///
        /// Creates an output context and invokes a write operation on it.
        ///
        /// <param name="payloadKind">The payload kind to write.</param>
        /// <param name="verifyHeaders">Optional action which will be called after the headers has been verified to perform payload specific verification.</param>
        /// <param name="writeAsyncAction">The write operation to invoke on the output.</param>
        /// <returns>Task which represents the pending write operation.</returns>
        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The output context is disposed by Dispose on the writer.")]
        private Task WriteToOutputAsync(ODataPayloadKind payloadKind, Action verifyHeaders, Func<ODataOutputContext, Task> writeAsyncAction)
        {
            // Set the content type header here since all headers have to be set before getting the stream
            this.SetOrVerifyHeaders(payloadKind);

            if (verifyHeaders != null)
            {
                verifyHeaders();
            }

            // Create the output context
            return ODataOutputContext.CreateOutputContextAsync(
                this.format,
                this.message,
                this.encoding,
                this.settings,
                this.writingResponse,
                this.model,
                this.urlResolver)

                .FollowOnSuccessWithTask(
                    (createOutputContextTask) =>
                    {
                        this.outputContext = createOutputContextTask.Result;
                        return writeAsyncAction(this.outputContext);
                    });
        }

        ///
        /// Creates an output context and invokes a write operation on it.
        ///
        /// <typeparam name="TResult">The type of the result of the write operation.</typeparam>
        /// <param name="payloadKind">The payload kind to write.</param>
        /// <param name="verifyHeaders">Optional action which will be called after the headers has been verified to perform payload specific verification.</param>
        /// <param name="writeFunc">The write operation to invoke on the output.</param>
        /// <returns>Task which represents the pending write operation.</returns>
        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The output context is disposed by Dispose on the writer.")]
        private Task<TResult> WriteToOutputAsync<TResult>(ODataPayloadKind payloadKind, Action verifyHeaders, Func<ODataOutputContext, Task<TResult>> writeFunc)
        {
            // Set the content type header here since all headers have to be set before getting the stream
            this.SetOrVerifyHeaders(payloadKind);

            if (verifyHeaders != null)
                    {
                verifyHeaders();
            }

            // Create the output context
            return ODataOutputContext.CreateOutputContextAsync(
                this.format,
                this.message,
                this.encoding,
                this.settings,
                this.writingResponse,
                this.model,
                this.urlResolver)

                .FollowOnSuccessWithTask(
                    (createOutputContextTask) =>
                    {
                        this.outputContext = createOutputContextTask.Result;
                        return writeFunc(this.outputContext);
                    });
            }
#endif
    }
}


text:
namespace base {
class ScopedClosureRunner;
class SequencedTaskRunner;
}  // namespace base

namespace drive {

namespace internal {

// Interface class used for getting the free disk space. Tests can inject an
// implementation that reports fake free disk space.
class FreeDiskSpaceGetterInterface {
 public:
  virtual ~FreeDiskSpaceGetterInterface() {}
  virtual int64 AmountOfFreeDiskSpace() = 0;
};

// FileCache is used to maintain cache states of FileSystem.
//
// All non-static public member functions, unless mentioned otherwise (see
// GetCacheFilePath() for example), should be run with |blocking_task_runner|.
class FileCache {
 public:
  // Enum defining type of file operation e.g. copy or move, etc.
  enum FileOperationType {
    FILE_OPERATION_MOVE = 0,
    FILE_OPERATION_COPY,
  };

  // |cache_file_directory| stores cached files.
  //
  // |blocking_task_runner| indicates the blocking worker pool for cache
  // operations. All operations on this FileCache must be run on this runner.
  // Must not be null.
  //
  // |free_disk_space_getter| is used to inject a custom free disk space
  // getter for testing. NULL must be passed for production code.
  //
  // Must be called on the UI thread.
  FileCache(ResourceMetadataStorage* storage,
            const base::FilePath& cache_file_directory,
            base::SequencedTaskRunner* blocking_task_runner,
            FreeDiskSpaceGetterInterface* free_disk_space_getter);

  // Returns true if the given path is under drive cache directory, i.e.
  // <user_profile_dir>/GCache/v1
  //
  // Can be called on any thread.
  bool IsUnderFileCacheDirectory(const base::FilePath& path) const;

  // Frees up disk space to store a file with |num_bytes| size content, while
  // keeping cryptohome::kMinFreeSpaceInBytes bytes on the disk, if needed.
  // Returns true if we successfully manage to have enough space, otherwise
  // false.
  bool FreeDiskSpaceIfNeededFor(int64 num_bytes);

  // Checks if file corresponding to |id| exists in cache, and returns
  // FILE_ERROR_OK with |cache_file_path| storing the path to the file.
  // |cache_file_path| must not be null.
  FileError GetFile(const std::string& id, base::FilePath* cache_file_path);

  // Stores |source_path| as a cache of the remote content of the file
  // with |id| and |md5|.
  // Pass an empty string as MD5 to mark the entry as dirty.
  FileError Store(const std::string& id,
                  const std::string& md5,
                  const base::FilePath& source_path,
                  FileOperationType file_operation_type);

  // Pins the specified entry.
  FileError Pin(const std::string& id);

  // Unpins the specified entry.
  FileError Unpin(const std::string& id);

  // Sets the state of the cache entry corresponding to |id| as mounted.
  FileError MarkAsMounted(const std::string& id,
                          base::FilePath* cache_file_path);

  // Sets the state of the cache entry corresponding to file_path as unmounted.
  FileError MarkAsUnmounted(const base::FilePath& file_path);

  // Opens the cache file corresponding to |id| for write. |file_closer| should
  // be kept alive until writing finishes.
  // This method must be called before writing to cache files.
  FileError OpenForWrite(const std::string& id,
                         scoped_ptr<base::ScopedClosureRunner>* file_closer);

  // Returns true if the cache file corresponding to |id| is write-opened.
  bool IsOpenedForWrite(const std::string& id);

  // Calculates MD5 of the cache file and updates the stored value.
  FileError UpdateMd5(const std::string& id);

  // Clears dirty state of the specified entry.
  FileError ClearDirty(const std::string& id);

  // Removes the specified cache entry and delete cache files if available.
  FileError Remove(const std::string& id);

  // Removes all the files in the cache directory.
  bool ClearAll();

  // Initializes the cache. Returns true on success.
  bool Initialize();

  // Destroys this cache. This function posts a task to the blocking task
  // runner to safely delete the object.
  // Must be called on the UI thread.
  void Destroy();

  // Moves files in the cache directory which are not managed by FileCache to
  // |dest_directory|.
  // |recovered_cache_info| should contain cache info recovered from the trashed
  // metadata DB. It is used to ignore non-dirty files.
  bool RecoverFilesFromCacheDirectory(
      const base::FilePath& dest_directory,
      const ResourceMetadataStorage::RecoveredCacheInfoMap&
          recovered_cache_info);

 private:
  friend class FileCacheTest;

  ~FileCache();

  // Returns absolute path of the file if it were cached or to be cached.
  //
  // Can be called on any thread.
  base::FilePath GetCacheFilePath(const std::string& id) const;

  // Checks whether the current thread is on the right sequenced worker pool
  // with the right sequence ID. If not, DCHECK will fail.
  void AssertOnSequencedWorkerPool();

  // Destroys the cache on the blocking pool.
  void DestroyOnBlockingPool();

  // Returns true if we have sufficient space to store the given number of
  // bytes, while keeping cryptohome::kMinFreeSpaceInBytes bytes on the disk.
  bool HasEnoughSpaceFor(int64 num_bytes, const base::FilePath& path);

  // Renames cache files from old "prefix:id.md5" format to the new format.
  // TODO(hashimoto): Remove this method at some point.
  bool RenameCacheFilesToNewFormat();

  // This method must be called after writing to a cache file.
  // Used to implement OpenForWrite().
  void CloseForWrite(const std::string& id);

  const base::FilePath cache_file_directory_;

  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;

  ResourceMetadataStorage* storage_;

  FreeDiskSpaceGetterInterface* free_disk_space_getter_;  // Not owned.

  // IDs of files being write-opened.
  std::map<std::string, int> write_opened_files_;

  // IDs of files marked mounted.
  std::set<std::string> mounted_files_;

  // Note: This should remain the last member so it'll be destroyed and
  // invalidate its weak pointers before any other members are destroyed.
  // This object should be accessed only on |blocking_task_runner_|.
  base::WeakPtrFactory<FileCache> weak_ptr_factory_;
  DISALLOW_COPY_AND_ASSIGN(FileCache);
};

}  // namespace internal
}  // namespace drive

#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_CACHE_H_

redpajama_set_name: RedPajamaGithub


text:
'use strict';

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    // don't forgot stuff you're loading off CDN
    files: [
      '../../dist/js/lib/angular.min.js',
      '../lib/angular/angular-mocks.js',
      //'../../dist/js/lib/angular-ui-router.min.js',
      //'../../dist/js/lib/jquery.min.js',
      //'../../src/js/lib/*.js',
      //'../../src/js/app/*.js',
      //'../../src/js/com.app.js',
      '../example/app.js',
      '../unit/**/*.js'
    ],

    // list of files to exclude
    exclude: [

    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {

    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['spec'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: [
        'PhantomJS'
        // , 'Chrome'
        // , 'Firefox'
        // , 'Safari'
    ],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false
  });
};


text:
<?php

namespace AppBundle\Controller;

use AppBundle\Entity\Participant;
use AppBundle\Entity\Question;
use AppBundle\Entity\Survey;
use AppBundle\Form\AskType;
use AppBundle\Form\ParticipantType;
use Doctrine\ORM\EntityRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Validator\Constraints as Constraints;

/**
 * Frontend der Umfrage
 *
 * @Route("/umfrage")
 */
class SurveyController extends Controller
{
    const ERROR_NO_OUTLET = 'Es konnte kein Betrieb zu dieser Umfrage gefunden werden.';
    const ERROR_NO_ACTIVE_OUTLET = 'Es konnte kein aktiver Betrieb zu dieser Umfrage gefunden werden.';

    /**
     * @Route("/{hash}", name="umfrage")
     * @Route("/{hash}/ea8f243d9885cf8ce9876a580224fd3c", name="umfrage_multi")
     *
     * @param Request $request
     * @param $hash
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
     * @return array
     *
     * @TODO: check multiple participation
     */
    public function indexAction(Request $request, $hash)
    {
        // prepare
        $session = new Session();
        $em = $this->getDoctrine()->getEntityManager();
        $outletRepo = $em->getRepository('AppBundle:Outlet');
        $surveyRepo = $em->getRepository('AppBundle:Survey');
        $questionsRepo = $em->getRepository('AppBundle:Question');
        $outletSurveyRepo = $em->getRepository('AppBundle:OutletSurvey');
        $participantRepo = $em->getRepository('AppBundle:Participant');
        $response = new Response();

        // get outlet by hash
        $outlet = $outletRepo->findOneBy(['hash' => $hash]);
        if (!$outlet) {
            return $this->renderError(self::ERROR_NO_OUTLET);
        }

        // get survey by outlet
        $survey = $surveyRepo->findCurrent();
        if (!$survey) {
            return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
        }

        // decide which template to show based on survey status
        switch ($survey->getStatus()) {
            default:
            case Survey::STATUS_UPCOMING:
                return $this->render('@App/Survey/upcoming.html.twig', ['survey' => $survey]);
                break;
            case Survey::STATUS_FINISHED:
                return $this->render('@App/Survey/finished.html.twig', ['survey' => $survey]);
                break;
            case Survey::STATUS_RUNNING:
                // get outlet-survey connection
                $outletSurvey = $outletSurveyRepo->findOneBy(['outlet' => $outlet, 'survey' => $survey]);
                if (!$outletSurvey || !$outletSurvey->getActive()) {
                    return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
                }

                // disable ip/cookie check for multiple participations
                $multi = $this->container->get('request')->get('_route') == 'umfrage_multi' ? 1 : 0;
                if ($multi) {
                    $session->set('multi', 1);
                } elseif ($session->has('multi')) {
                    $session->remove('multi');
                }

                // get participant by cookie or ip
                $participant = $participantRepo->findOneByCookieOrIp(
                    $request->cookies->get(md5($survey->getName())),
                    $request->getClientIp(),
                    $outlet,
                    $survey
                );

                // init new participant if no existing one was found
                if (!$participant || $multi) {
                    $cookieHash = md5(uniqid());
                    $questionsHash = $questionsRepo->getQuestionsHash($survey);

                    $participant = new Participant();
                    $participant->setCookieHash($cookieHash);
                    $participant->setQuestionsHash($questionsHash);
                    $participant->setIp($request->getClientIp());
                    $participant->setUserAgent($request->headers->get('User-Agent'));
                    $participant->setOutlet($outlet);
                    $participant->setSurvey($survey);
                    $participant->setStart(time());

                    // save new participant
                    $em->persist($participant);
                    $em->flush();

                    // and give him a cookie (expiring in 31 days)
                    $response->headers->setCookie(new Cookie(md5($survey->getName()), $cookieHash, time() + 31 * 24 * 60 * 60));
                }

                // init questions enabled
                $session->set('questionsEnabled', []);
                if (!$session->has('questionsEnabled')) {
                    $session->set('questionsEnabled', []);
                }

                return $this->render(
                    '@App/Survey/running.html.twig',
                    [
                        'survey' => $survey,
                        'hash' => $hash
                    ],
                    $response
                );
                break;
        }
    }

    /**
     * @Route("/{hash}/ueber-dich", name="umfrage_about_you")
     * @Template()
     *
     * @param Request $request
     * @param $hash
     * @return array
     */
    public function aboutYouAction(Request $request, $hash)
    {
        // prepare
        $em = $this->getDoctrine()->getEntityManager();
        $outletRepo = $em->getRepository('AppBundle:Outlet');
        $surveyRepo = $em->getRepository('AppBundle:Survey');
        $outletSurveyRepo = $em->getRepository('AppBundle:OutletSurvey');
        $questionsRepo = $em->getRepository('AppBundle:Question');
        $participantRepo = $em->getRepository('AppBundle:Participant');

        // get outlet by hash
        $outlet = $outletRepo->findOneBy(['hash' => $hash]);
        if (!$outlet) {
            return $this->renderError(self::ERROR_NO_OUTLET);
        }

        // get survey by outlet
        $survey = $surveyRepo->findCurrent();
        if (!$survey) {
            return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
        }

        // get outlet-survey connection
        $outletSurvey = $outletSurveyRepo->findOneBy(['outlet' => $outlet, 'survey' => $survey]);
        if (!$outletSurvey || !$outletSurvey->getActive()) {
            return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
        }

        // get participant by cookie or ip
        $participant = $participantRepo->findOneByCookieOrIp(
            $request->cookies->get(md5($survey->getName())),
            $request->getClientIp(),
            $outlet,
            $survey
        );

        if (!$participant) {
            return $this->redirectToRoute('umfrage', ['hash' => $hash]);
        }

        // create and handle form
        $form = $this->createForm(new ParticipantType(), $participant, array(
            'action' => $this->generateUrl('umfrage_about_you', ['hash' => $hash]),
            'method' => 'POST',
        ));
        $form->handleRequest($request);

        if ($form->isValid()) {
            $em->flush();

            return $this->redirectToRoute('umfrage_ask', [
                'hash' => $hash,
                'current' => 1,
                'total' => count($questionsRepo->getQuestionsFromHash($participant->getQuestionsHash()))
            ]);
        }

        return [
            'form' => $form->createView(),
            'hash' => $hash
        ];
    }

    /**
     * @Route("/{hash}/frage-{current}-von-{total}", name="umfrage_ask")
     * @Template()
     *
     * @param Request $request
     * @param $hash
     * @param $current
     * @param $total
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function askAction(Request $request, $hash, $current, $total)
    {
        // prepare
        $session = new Session();
        $em = $this->getDoctrine()->getEntityManager();
        $outletRepo = $em->getRepository('AppBundle:Outlet');
        $surveyRepo = $em->getRepository('AppBundle:Survey');
        $outletSurveyRepo = $em->getRepository('AppBundle:OutletSurvey');
        $participantRepo = $em->getRepository('AppBundle:Participant');
        $questionRepo = $em->getRepository('AppBundle:Question');
        $answerRepo = $em->getRepository('AppBundle:Answer');

        // get outlet by hash
        $outlet = $outletRepo->findOneBy(['hash' => $hash]);
        if (!$outlet) {
            return $this->renderError(self::ERROR_NO_OUTLET);
        }

        // get survey by outlet
        $survey = $surveyRepo->findCurrent();
        if (!$survey) {
            return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
        }

        // get outlet-survey connection
        $outletSurvey = $outletSurveyRepo->findOneBy(['outlet' => $outlet, 'survey' => $survey]);
        if (!$outletSurvey || !$outletSurvey->getActive()) {
            return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
        }

        // get participant by cookie or ip
        $participant = $participantRepo->findOneByCookieOrIp(
            $request->cookies->get(md5($survey->getName())),
            $request->getClientIp(),
            $outlet,
            $survey
        );
        if (!$participant) {
            return $this->redirectToRoute('umfrage', ['hash' => $hash]);
        }

        // get questions pool for participants
        $questions = $questionRepo->getQuestionsFromHash($participant->getQuestionsHash());
        if (!count($questions)) {
            return $this->redirectToRoute('umfrage_finish', ['hash' => $hash]);
        }

        // get current question
        $question = $questions[$current - 1];
        $form = $this->createAskForm($question, $answerRepo, $participant, $survey, $hash, $current, $total);

        // checking if question was reached by naturally proceeding the survey and not manipulating the url
        if ($current != 1 && (!$session->has('questionsEnabled') || !in_array($current, $session->get('questionsEnabled')))) {
            return $this->redirectToRoute('umfrage_ask', ['hash' => $hash, 'current' => $current - 1, 'total' => $total]);
        }

        return [
            'outlet' => $outlet,
            'question' => $question,
            'form' => $form->createView(),
            'current' => $current,
            'total' => $total,
            'hash' => $hash
        ];
    }

    /**
     * @Route("/{hash}/frage-{current}-von-{total}/save", name="umfrage_save")
     * @Method("POST")
     *
     * @param Request $request
     * @param $hash
     * @param $current
     * @param $total
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     *
     * @TODO: Validation
     */
    public function saveAction(Request $request, $hash, $current, $total)
    {
        // prepare
        $session = new Session();
        $em = $this->getDoctrine()->getEntityManager();
        $outletRepo = $em->getRepository('AppBundle:Outlet');
        $surveyRepo = $em->getRepository('AppBundle:Survey');
        $outletSurveyRepo = $em->getRepository('AppBundle:OutletSurvey');
        $participantRepo = $em->getRepository('AppBundle:Participant');
        $questionRepo = $em->getRepository('AppBundle:Question');
        $answerRepo = $em->getRepository('AppBundle:Answer');

        // get outlet by hash
        $outlet = $outletRepo->findOneBy(['hash' => $hash]);
        if (!$outlet) {
            return $this->renderError(self::ERROR_NO_OUTLET);
        }

        // get survey by outlet
        $survey = $surveyRepo->findCurrent();
        if (!$survey) {
            return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
        }

        // get outlet-survey connection
        $outletSurvey = $outletSurveyRepo->findOneBy(['outlet' => $outlet, 'survey' => $survey]);
        if (!$outletSurvey || !$outletSurvey->getActive()) {
            return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
        }

        // get participant by cookie or ip
        $participant = $participantRepo->findOneByCookieOrIp(
            $request->cookies->get(md5($survey->getName())),
            $request->getClientIp(),
            $outlet,
            $survey
        );

        if (!$participant) {
            return $this->redirectToRoute('umfrage', ['hash' => $hash]);
        }

        // get questions pool for participants
        $questions = $questionRepo->getQuestionsFromHash($participant->getQuestionsHash());
        // get current question
        /** @var Question $question */
        $question = $questions[$current - 1];
        // bind form to it
        $form = $this->createAskForm($question, $answerRepo, $participant, $survey, $hash, $current, $total);
        $form->handleRequest($request);

        // and save the answer
        if ($question->getType() == Question::TYPE_WRAPPER) {
            $childQuestions = $question->getChildren()->toArray();
            foreach ($childQuestions as $childQuestion) {
                $answerRepo->save($childQuestion, $outlet, $survey, $participant, $form);
            }
        } else {
            $answerRepo->save($question, $outlet, $survey, $participant, $form);
        }

        // enable next question to check if question was reached by naturally
        // proceeding the survey and not manipulating the url
        if ($session->has('questionsEnabled')) {
            $questionsEnabled = $session->get('questionsEnabled');
            $questionsEnabled[$current + 1] = $current + 1;
            $session->set('questionsEnabled', $questionsEnabled);
        } else {
            $session->set('questionsEnabled', [$current + 1 => $current + 1]);
        }

        // decide where to go next
        if ($form->has('prev') && $form->get('prev')->isClicked()) {
            if ($current == 1) {
                return $this->redirectToRoute('umfrage_about_you', ['hash' => $hash]);
            }
            return $this->redirectToRoute('umfrage_ask', ['hash' => $hash, 'current' => $current - 1, 'total' => $total]);
        } elseif ($form->has('next') && $form->get('next')->isClicked()) {
            return $this->redirectToRoute('umfrage_ask', ['hash' => $hash, 'current' => $current + 1, 'total' => $total]);
        } elseif ($form->has('finish') && $form->get('finish')->isClicked()) {
            return $this->redirectToRoute('umfrage_finish', ['hash' => $hash]);
        }

        return $this->render('@App/Survey/layout.html.twig');
    }

    /**
     * @Route("/{hash}/ende", name="umfrage_finish")
     * @Template()
     * @param Request $request
     * @param $hash
     * @return array
     */
    public function finishAction(Request $request, $hash)
    {
        // prepare
        $em = $this->getDoctrine()->getEntityManager();
        $outletRepo = $em->getRepository('AppBundle:Outlet');
        $surveyRepo = $em->getRepository('AppBundle:Survey');
        $outletSurveyRepo = $em->getRepository('AppBundle:OutletSurvey');
        $participantRepo = $em->getRepository('AppBundle:Participant');

        // get outlet by hash
        $outlet = $outletRepo->findOneBy(['hash' => $hash]);
        if (!$outlet) {
            return $this->renderError(self::ERROR_NO_OUTLET);
        }

        // get survey by outlet
        $survey = $surveyRepo->findCurrent();
        if (!$survey) {
            return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
        }

        // get outlet-survey connection
        $outletSurvey = $outletSurveyRepo->findOneBy(['outlet' => $outlet, 'survey' => $survey]);
        if (!$outletSurvey || !$outletSurvey->getActive()) {
            return $this->renderError(self::ERROR_NO_ACTIVE_OUTLET);
        }

        // get participant by cookie or ip
        $participant = $participantRepo->findOneByCookieOrIp(
            $request->cookies->get(md5($survey->getName())),
            $request->getClientIp(),
            $outlet,
            $survey
        );

        if (!$participant) {
            return $this->redirectToRoute('umfrage', ['hash' => $hash]);
        }

        // set endtime for this participant
        // from now on this participant is blocked from the survey
        if (!$participant->getEnd()) {
            $participant->setEnd(time());
        }

        // save email if provided
        $emailProvided = $request->request->has('email');
        $emailValid = null;
        $email = $emailProvided ? trim($request->request->get('email')) : '';
        if ($emailProvided) {
            $emailConstraint = new Constraints\Email();
            $notBlankConstraint = new Constraints\NotBlank();
            $emailValid = !count($this->get('validator')->validate(
                $email,
                [$emailConstraint, $notBlankConstraint]
            ));

            if ($emailValid) {
                $participant->setEmail($email);
            }
        }

        $em->flush();

        return [
            'participant' => $participant,
            'emailProvided' => $emailProvided,
            'emailValid' => $emailValid,
            'hash' => $hash,
            'survey' => $survey
        ];
    }

    /**
     * @Route("/{hash}/gesperrt", name="umfrage_blocked")
     * @Template()
     *
     * @return array
     */
    public function blockedAction()
    {
        return array();
    }

    private function createAskForm(Question $question, EntityRepository $answerRepo, Participant $participant, Survey $survey, $hash, $current, $total)
    {
        return $this->createForm(new AskType($question, $answerRepo, $participant, $survey, $current, $total), null, array(
            'action' => $this->generateUrl('umfrage_save', ['hash' => $hash, 'current' => $current, 'total' => $total]),
            'method' => 'POST',
        ));
    }

    private function renderError($message)
    {
        return $this->render('@App/Survey/error.html.twig', [
            'message' => $message
        ]);
    }
}


text:
//  Copyright (c) 2007-2008 Facebook
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
// See accompanying file LICENSE or visit the Scribe site at:
// http://developers.facebook.com/scribe/
//
// @author Bobby Johnson
// @author James Wang
// @author Jason Sobel
// @author Anthony Giardullo

#ifndef SCRIBE_STORE_QUEUE_H
#define SCRIBE_STORE_QUEUE_H

#include <string>
#include <queue>
#include <vector>
#include <pthread.h>

#include "src/gen-cpp/scribe.h"
#include "store.h"

/*
 * This class implements a queue and a thread for dispatching
 * events to a store. It creates a store object of the requested
 * type, which can in turn create and manage other store objects.
 */
class StoreQueue {
 public:
  StoreQueue(const std::string& type, const std::string& category,
             unsigned check_period, bool is_model=false, bool multi_category=false);
  StoreQueue(const boost::shared_ptr<StoreQueue> example,
             const std::string &category);
  virtual ~StoreQueue();

  void addMessage(logentry_ptr_t entry);
  void configureAndOpen(pStoreConf configuration); // closes first if already open
  void open();                                     // closes first if already open
  void stop();
  boost::shared_ptr<Store> copyStore(const std::string &category);
  std::string getStatus(); // An empty string means OK, anything else is an error
  std::string getBaseType();
  std::string getCategoryHandled();
  bool isModelStore() { return isModel;}

  // this needs to be public for the thread creation to get to it,
  // but no one else should ever call it.
  void threadMember();

  // WARNING: don't expect this to be exact, because it could change after you check.
  //          This is only for hueristics to decide when we're overloaded.
  unsigned long getSize();

 private:
  void storeInitCommon();
  void configureInline(pStoreConf configuration);
  void openInline();
  void processFailedMessages(boost::shared_ptr<logentry_vector_t> messages);

  // implementation of queues and thread
  enum store_command_t {
    CMD_CONFIGURE,
    CMD_OPEN,
    CMD_STOP
  };

  class StoreCommand {
  public:
    store_command_t command;
    pStoreConf configuration;

    StoreCommand(store_command_t cmd, pStoreConf config = pStoreConf())
      : command(cmd), configuration(config) {};
  };

  typedef std::queue<StoreCommand> cmd_queue_t;

  // messages and commands are in different queues to allow bulk
  // handling of messages. This means that order of commands with
  // respect to messages is not preserved.
  cmd_queue_t cmdQueue;
  boost::shared_ptr<logentry_vector_t> msgQueue;
  boost::shared_ptr<logentry_vector_t> failedMessages;
  unsigned long msgQueueSize;   // in bytes
  pthread_t storeThread;

  // Mutexes
  pthread_mutex_t cmdMutex;     // Must be held to read/modify cmdQueue
  pthread_mutex_t msgMutex;     // Must be held to read/modify msgQueue
  pthread_mutex_t hasWorkMutex; // Must be held to read/modify hasWork
  // If acquiring multiple mutexes, always acquire in this order:
  // {cmdMutex, msgMutex, hasWorkMutex}

  bool hasWork;  // whether there are messages or commands queued
  pthread_cond_t hasWorkCond; // cond variable to wait on for hasWork

  bool stopping;
  bool isModel;
  bool multiCategory; // Whether multiple categories are handled

  // configuration
  std::string   categoryHandled;  // what category this store is handling
  time_t        checkPeriod;      // how often to call periodicCheck in seconds
  unsigned long targetWriteSize;  // in bytes
  time_t        maxWriteInterval; // in seconds
  bool          mustSucceed;      // Always retry even if secondary fails

  // Store that will handle messages. This can contain other stores.
  boost::shared_ptr<Store> store;
};

#endif //!defined SCRIBE_STORE_QUEUE_H


text:
  Broye-Aubigney-Montseugny est
       un village
       situé dans le département de Haute-Saône en Franche-Comté. Elle comptait 463 habitants en 2008.

À coté de Broye-Aubigney-Montseugny sont localisées les villes de
La Grande-Résie située à 5 km, 89 habitants,
Perrigny-sur-l'Ognon localisée à 4 km, 627 habitants,
Pesmes à 5 km, 1 107 habitants,
Champagney située à 5 km, 305 habitants,
Cléry située à 2 km, 133 habitants,
Sauvigney-lès-Pesmes localisée à 4 km, 172 habitants,
 entre autres. De plus, Broye-Aubigney-Montseugny est située à seulement 24 km de Dole.

Si vous envisagez de venir habiter à Broye-Aubigney-Montseugny, vous pourrez aisément trouver une maison à acheter.

La ville propose quelques  équipements sportifs, elle propose entre autres un terrain de tennis.

Le parc de logements, à Broye-Aubigney-Montseugny, était réparti en 2011 en six appartements et 293 maisons soit
 un marché plutôt équilibré.


text:
"use strict";

/* import-globals-from common.js */

async function init() {
  const user = document.querySelector("#moz_login span.anchor").textContent;
  const headers = document.querySelectorAll("h3");
  for (const h of headers) {
    if (!h.textContent.endsWith("review")) {
      continue;
    }
    for (const tr of h.nextElementSibling.querySelectorAll("tr")) {
      const a = tr.querySelector("a[href^='show_bug.cgi?id=']");
      const bug_id = a && a.href.match(/(\d+)$/)[1];
      const visible = await storage(bug_id);
      const td = tr.firstElementChild;

      if (a && !td.textContent.includes(user) && !visible) {
        td.textContent = "[redacted]";
      }
    }
  }
}

init();


text:
Sitd
================

Panel para notas o textos para poder presentarlos desde Devmg

##FrontEnd
Guia para configurar entorno de frontend.

Version
----

1.0

Requisitos previos
-----------
* Instalar el bower
* Instalar gulp

Instalacion del bower
--------------

```sh
npm install -g bower
```
Instalacion del Gulp
--------------

```sh
npm install -g gulp
```

Instalacion de las dependencias
--------------

### Instalar dependencias de node

```sh
npm install
```

### Instalar dependencias de bower

```sh
bower install
```

### Correr el servidor de desarrollo

```sh
gulp

----
[15:45:28] Using gulpfile D:\mauricio\www\dev
[15:45:28] Starting 'server'...
[15:45:28] Server started http://localhost:80
[15:45:28] LiveReload started on port 35729

```


text:
class SchemeType:
    def __eq__(a, b):
        if not ( isinstance(a, SchemeType) and isinstance(b, SchemeType)):
            return False
        elif a.type != b.type:
            return False
        elif a.value != b.value:
            return False
        else:
            return True

    def __repr__(self):
        return "<%s:%s>" % (self.__class__.__name__, self.value)

class SchemeProcedure(SchemeType):
    def __init__(self, name, impl, lenArgs = None):
        self.name = name
        self.impl = impl
        self.type = "Procedure"
        self.lenArgs = lenArgs
        self.value = name # needed for transpiler
    def __str__(self):
        return '<Procedure:%s>' % self.name
    def __repr__(self):
        return "<%s:%s>" % (self.__class__.__name__, self.name)

class SchemeString(SchemeType):
    def __init__(self, value):
        self.value = value
        self.type = 'String'
    def __str__(self):
        return '"%s"' % (self.value)

class SchemeNumber(SchemeType):
    def __init__(self, value):
        self.value = value
        self.type = 'Number'
    def impl(self, *args):
        return self.value
    def __str__(self):
        return '%s' % (self.value)

class SchemeSymbol(SchemeType):
    def __init__(self, value):
        self.value = value
        self.type = 'Symbol'
    def __str__(self):
        return '%s' % (self.value)

class SchemeTrue(SchemeType):
    def __init__(self):
        self.type = "SchemeTrue"
        self.value = "True"
    def __str__(self):
        return '#t'

class SchemeFalse(SchemeType):
    def __init__(self):
        self.type = "SchemeFalse"
        self.value = "False"
    def __str__(self):
        return '#f'

class SchemeNil(SchemeType):
    def __init__(self):
        self.type = "SchemeNil"
        self.value = "Nil"
    def __str__(self):
        return "()"

class SchemeCons(SchemeType):
    def __init__(self, car, cdr):
        self.car = car
        self.cdr = cdr
        self.type = "SchemeCons"
    def __str__(self):
        ret = "("
        if isinstance(self.car, SchemeCons):
            ret += self.car._str_helper()
        else:
            ret +=  str(self.car)
        if isinstance(self.cdr, SchemeNil):
            return ret + ")"
        if isinstance(self.cdr, SchemeCons):
            return ret + " " + self.cdr._str_helper()
        else:
            return ret + (". %s)" % (self.cdr))

    def _str_helper(self):
        ret = ""
        if isinstance(self.car, SchemeCons):
            ret += "(" + self.car._str_helper()
        else:
            ret +=  str(self.car)
        if isinstance(self.cdr, SchemeNil):
            return ret + ")"
        if isinstance(self.cdr, SchemeCons):
            return ret + " " + self.cdr._str_helper()
        else:
            return ret + (" . %s)" % (self.cdr))

    def __eq__(self, other):
        if not ( isinstance(self, SchemeCons) and isinstance(other, SchemeCons)):
            return False
        elif self.car != other.car or self.cdr != other.cdr:
            return False
        else:
            return True
    def __repr__(self):
        return "<SchemeCons: (%s.%s)>" % (self.car, self.cdr)

class SchemeException(Exception):
    pass

class SchemeEnvironment:
    def __init__(self, params = None, args = None , parentEnv=None):
        self.parentEnv = parentEnv
        self._dict = {}
        values = []
        if params != None and args != None:
            [values.append(vals.value) for vals in params] ##hacky
            self._dict = dict(zip(values, args))

    def find(self, key):
        val = self._dict.get(key)
        if val != None:
            return val
        else:
            if self.parentEnv != None:
                return self.parentEnv.find(key)
            else:
                raise SchemeException("Undefined Symbol %s!" % (key))

    def update(self, dict):
        for key  in dict.keys():
            self._dict[key] = dict[key]

    def set(self, key, value):
        if key in self._dict:
            raise SchemeException("%s has already been defined. Use set! to redefine" % (key) )
        else:
            self._dict[key]=value

    def set_overwrite(self, key, value):
        if key in self._dict:
            self._dict[key] = value
        else:
            self.parentEnv.set_overwrite(key, value)

class SchemeRootEnviornment(SchemeEnvironment):
    def set(self, key, value):
            self._dict[key]=value
    def set_overwrite(self, key, value):
        if key in self._dict:
            self._dict[key] = value
        else:
            raise SchemeException("%s has not been definied yet!" % (key))


text:
@interface PodsDummy_Pods_FZNetworking_Example : NSObject
@end
@implementation PodsDummy_Pods_FZNetworking_Example
@end


text:
@echo off

echo BUILDING NoSDBPS.sln
echo ======================
@%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ..\..\Tool\NoSDBPSProvider\NoSDBPS.sln /t:Rebuild /p:Configuration=Release /p:platform="Any CPU"
set BUILD_STATUS=%ERRORLEVEL%
if not %BUILD_STATUS%==0 goto NoSDBPS
echo NoSDBPS BUILD ALL SUCCEEDED
pause
exit /b 0

:NoSDBPS
echo FAILED TO BUILD NoSDBPS.sln
echo =============================
pause
exit /b 1


text:
/// jsonp.js --- Abstracts over JSONP requests
//
// Copyright (c) 2012 Quildreen Motta
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/// Module iris.jsonp

//// -- Dependencies ----------------------------------------------------------
var utils  = require('./utils')
var cassie = require('cassie')

//// -- Aliases ---------------------------------------------------------------
var keys               = Object.keys
var call               = Function.call
var to_array           = call.bind([].slice)
var build_query_string = utils.build_query_string
var Promise            = cassie.Promise

//// -- Helpers ---------------------------------------------------------------
window.__iris_callbacks__ = { }
var id_poll = []
var request_id = 0

var head = document.getElementsByTagName('head')[0]

function get_callback() {
  return id_poll.length?  'f' + id_poll.pop()
  :      /* otherwise */  'f' + ++request_id }

function noop() { }

//// -- Public interface ------------------------------------------------------
var active = []

var PromiseP = Promise.derive({
  init:
  function _init(uri, callback, options) {
    Promise.init.call(this)
    this.uri      = uri
    this.options  = options
    this.callback = callback

    return this }
})

function request(uri, options) {
  options = options || {}
  options.query = options.query || {}

  var callback_field = options.query.callback || 'callback'
  var callback = get_callback()
  var script = document.createElement('script')
  var promise = PromiseP.make(uri, callback, options)

  active.push(promise)

  __iris_callbacks__[callback] = promise.bind.bind(promise)
  script.onerror = promise.fail.bind(promise)

  promise.on('done', clean)

  options.query[callback_field] = '__iris_callbacks__.' + callback
  script.src = build_query_string(uri, options.query)
  script.async = true

  setTimeout(function() {  head.appendChild(script) })

  return promise

  function clean() {
    active.splice(active.indexOf(promise), 1)
    id_poll.push(callback.slice(1))
    __iris_callbacks__[callback] = noop
    script.parentNode.removeChild(script) }}

//// -- Exports ---------------------------------------------------------------
module.exports = { PromiseP: PromiseP
                 , request:  request
                 , active:   active }