Exemplo n.º 1
0
        /// <summary>
        /// Gets an array <see cref="IDicomCodecFactory"/> instances.
        /// </summary>
        /// <returns></returns>
        public static IDicomCodecFactory[] GetCodecFactories()
        {
            DicomCodecFactoryExtensionPoint ep = new DicomCodecFactoryExtensionPoint();

            object[]             extensions     = ep.CreateExtensions();
            IDicomCodecFactory[] codecFactories = new IDicomCodecFactory[extensions.Length];
            extensions.CopyTo(codecFactories, 0);
            return(codecFactories);
        }
        private bool ProcessWorkQueueUid(Model.WorkQueue item, WorkQueueUid sop, StudyXml studyXml, IDicomCodecFactory theCodecFactory)
        {
            Platform.CheckForNullReference(item, "item");
            Platform.CheckForNullReference(sop, "sop");
            Platform.CheckForNullReference(studyXml, "studyXml");

            if (!studyXml.Contains(sop.SeriesInstanceUid, sop.SopInstanceUid))
            {
                // Uid was inserted but not in the study xml.
                // Auto-recovery might have detect problem with that file and remove it from the study.
                // Assume the study xml has been corrected and ignore the uid.
                Platform.Log(LogLevel.Warn, "Skipping SOP {0} in series {1}. It is no longer part of the study.", sop.SopInstanceUid, sop.SeriesInstanceUid);

                // Delete it out of the queue
                DeleteWorkQueueUid(sop);
                return true;
            }

            string basePath = Path.Combine(StorageLocation.GetStudyPath(), sop.SeriesInstanceUid);
            basePath = Path.Combine(basePath, sop.SopInstanceUid);
            string path;
            if (sop.Extension != null)
                path = basePath + "." + sop.Extension;
            else
                path = basePath + ServerPlatform.DicomFileExtension;

            try
            {
                ProcessFile(item, sop, path, studyXml, theCodecFactory);

                // WorkQueueUid has been deleted out by the processor

                return true;
            }
            catch (Exception e)
            {
                if (e.InnerException != null && e.InnerException is DicomCodecUnsupportedSopException)
                {
                    Platform.Log(LogLevel.Warn, e, "Instance not supported for compressor: {0}.  Deleting WorkQueue entry for SOP {1}", e.Message, sop.SopInstanceUid);

                    item.FailureDescription = e.InnerException != null ? e.InnerException.Message : e.Message;

                    // Delete it out of the queue
                    DeleteWorkQueueUid(sop);

                    return false;
                }
                Platform.Log(LogLevel.Error, e, "Unexpected exception when compressing file: {0} SOP Instance: {1}", path, sop.SopInstanceUid);
                item.FailureDescription = e.InnerException != null ? e.InnerException.Message : e.Message;

                sop.FailureCount++;

                UpdateWorkQueueUid(sop);

                return false;
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Set an <see cref="IDicomCodecFactory"/> for a transfer syntax, overriding the current value.
 /// </summary>
 /// <param name="syntax">The transfer syntax of the codec.</param>
 /// <param name="factory">The factory for the codec.</param>
 public static void SetCodec(TransferSyntax syntax, IDicomCodecFactory factory)
 {
     if (factory != null)
     {
         _dictionary[syntax] = factory;
     }
     else
     {
         _dictionary.Remove(syntax);
     }
 }
Exemplo n.º 4
0
        public DicomCompressCommand(DicomMessageBase file, XmlDocument parms, bool failOnCodecException)
            : base("DICOM Compress Command", true)
        {
            _file = file;
            _failOnCodecException = failOnCodecException;

            XmlElement element = parms.DocumentElement;

            string syntax = element.Attributes["syntax"].Value;

            _syntax = TransferSyntax.GetTransferSyntax(syntax);
            if (_syntax == null)
            {
                string failureDescription =
                    String.Format("Invalid transfer syntax in compression command: {0}", element.Attributes["syntax"].Value);
                Platform.Log(LogLevel.Error, "Error with input syntax: {0}", failureDescription);
                throw new DicomCodecException(failureDescription);
            }

            IDicomCodecFactory[] codecs          = DicomCodecRegistry.GetCodecFactories();
            IDicomCodecFactory   theCodecFactory = null;

            foreach (IDicomCodecFactory codec in codecs)
            {
                if (codec.CodecTransferSyntax.Equals(_syntax))
                {
                    theCodecFactory = codec;
                    break;
                }
            }

            if (theCodecFactory == null)
            {
                string failureDescription = String.Format("Unable to find codec for compression: {0}", _syntax.Name);
                Platform.Log(LogLevel.Error, "Error with compression input parameters: {0}", failureDescription);
                throw new DicomCodecException(failureDescription);
            }

            _codec = theCodecFactory.GetDicomCodec();
            _parms = theCodecFactory.GetCodecParameters(parms);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Process all of the SOP Instances associated with a <see cref="WorkQueue"/> item.
        /// </summary>
        /// <param name="item">The <see cref="WorkQueue"/> item.</param>
        /// <returns>A value indicating whether the uid list has been successfully processed</returns>
        /// <param name="theCodecFactory">The factor for doing the compression</param>
        protected bool ProcessUidList(Model.WorkQueue item, IDicomCodecFactory theCodecFactory)
        {
            StudyXml studyXml = LoadStudyXml(StorageLocation);

            int successfulProcessCount = 0;
            int totalCount             = WorkQueueUidList.Count;

            foreach (WorkQueueUid sop in WorkQueueUidList)
            {
                if (sop.Failed)
                {
                    continue;
                }

                if (CancelPending)
                {
                    Platform.Log(LogLevel.Info,
                                 "Received cancel request while compressing study {0}.  {1} instances successfully processed.",
                                 StorageLocation.StudyInstanceUid, successfulProcessCount);

                    return(successfulProcessCount > 0);
                }

                if (ProcessWorkQueueUid(item, sop, studyXml, theCodecFactory))
                {
                    successfulProcessCount++;
                }
            }

            if (successfulProcessCount > 0)
            {
                Platform.Log(LogLevel.Info, "Completed compression of study {0}. {1} instances successfully processed.",
                             StorageLocation.StudyInstanceUid, successfulProcessCount);
            }

            return(successfulProcessCount > 0 && totalCount == successfulProcessCount);
        }
Exemplo n.º 6
0
		/// <summary>
		/// Gets an array <see cref="IDicomCodecFactory"/> instances.
		/// </summary>
		/// <returns></returns>
		public static IDicomCodecFactory[] GetCodecFactories()
		{
			DicomCodecFactoryExtensionPoint ep = new DicomCodecFactoryExtensionPoint();
			object[] extensions = ep.CreateExtensions();
			IDicomCodecFactory[] codecFactories = new IDicomCodecFactory[extensions.Length];
			extensions.CopyTo(codecFactories, 0);
			return codecFactories;
		}
		protected void ProcessFile(Model.WorkQueue item, WorkQueueUid sop, string path, StudyXml studyXml, IDicomCodecFactory theCodecFactory)
		{
			DicomFile file;

			_instanceStats = new CompressInstanceStatistics();

			_instanceStats.ProcessTime.Start();

			// Use the command processor for rollback capabilities.
            using (ServerCommandProcessor processor = new ServerCommandProcessor("Processing WorkQueue Compress DICOM File"))
            {
                string modality = String.Empty;

                try
                {
                    file = new DicomFile(path);

                    _instanceStats.FileLoadTime.Start();
                    file.Load(DicomReadOptions.StorePixelDataReferences | DicomReadOptions.Default);
                    _instanceStats.FileLoadTime.End();

                	modality = file.DataSet[DicomTags.Modality].GetString(0, String.Empty);

                    FileInfo fileInfo = new FileInfo(path);
                    _instanceStats.FileSize = (ulong)fileInfo.Length;

                    // Get the Patients Name for processing purposes.
                    String patientsName = file.DataSet[DicomTags.PatientsName].GetString(0, "");

                    if (file.TransferSyntax.Equals(theCodecFactory.CodecTransferSyntax))
                    {
						// Delete the WorkQueueUid item
						processor.AddCommand(new DeleteWorkQueueUidCommand(sop));

						// Do the actual processing
						if (!processor.Execute())
						{
							Platform.Log(LogLevel.Warn, "Failure deleteing WorkQueueUid: {0} for SOP: {1}", processor.Description, file.MediaStorageSopInstanceUid);
							Platform.Log(LogLevel.Warn, "Compression file that failed: {0}", file.Filename);
						}
						else
						{
							Platform.Log(LogLevel.Warn, "Skip compressing SOP {0}. Its current transfer syntax is {1}",
							             file.MediaStorageSopInstanceUid, file.TransferSyntax.Name);
						}
                    }
                    else
                    {
                        IDicomCodec codec = theCodecFactory.GetDicomCodec();

                        // Create a context for applying actions from the rules engine
                        var context = new ServerActionContext(file, StorageLocation.FilesystemKey, ServerPartition, item.StudyStorageKey);
                        context.CommandProcessor = processor;
                        
                        var parms = theCodecFactory.GetCodecParameters(item.Data);
                        var compressCommand =
                            new DicomCompressCommand(context.Message, theCodecFactory.CodecTransferSyntax, codec, parms);
                        processor.AddCommand(compressCommand);

                        var save = new SaveDicomFileCommand(file.Filename, file, false);
                        processor.AddCommand(save);

                        // Update the StudyStream object, must be done after compression
                        // and after the compressed image has been successfully saved
                        var insertStudyXmlCommand = new UpdateStudyXmlCommand(file, studyXml, StorageLocation);
                        processor.AddCommand(insertStudyXmlCommand);

						// Delete the WorkQueueUid item
                    	processor.AddCommand(new DeleteWorkQueueUidCommand(sop));

                        // Do the actual processing
                        if (!processor.Execute())
                        {
                            _instanceStats.CompressTime.Add(compressCommand.CompressTime);
                            Platform.Log(LogLevel.Error, "Failure compressing command {0} for SOP: {1}", processor.Description, file.MediaStorageSopInstanceUid);
                            Platform.Log(LogLevel.Error, "Compression file that failed: {0}", file.Filename);
                            throw new ApplicationException("Unexpected failure (" + processor.FailureReason + ") executing command for SOP: " + file.MediaStorageSopInstanceUid,processor.FailureException);
                        }
                    	_instanceStats.CompressTime.Add(compressCommand.CompressTime);
                    	Platform.Log(ServerPlatform.InstanceLogLevel, "Compress SOP: {0} for Patient {1}", file.MediaStorageSopInstanceUid,
                    	             patientsName);
                    }
                    
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Error, e, "Unexpected exception when {0}.  Rolling back operation.",
                                 processor.Description);
                    processor.Rollback();

                	throw;
                }
                finally
                {
                    _instanceStats.ProcessTime.End();
                    _studyStats.AddSubStats(_instanceStats);

                    _studyStats.StudyInstanceUid = StorageLocation.StudyInstanceUid;
                    if (String.IsNullOrEmpty(modality) == false)
                        _studyStats.Modality = modality;

                    // Update the statistics
                    _studyStats.NumInstances++;
                }
            }
		}
		/// <summary>
		/// Process all of the SOP Instances associated with a <see cref="WorkQueue"/> item.
		/// </summary>
		/// <param name="item">The <see cref="WorkQueue"/> item.</param>
		/// <returns>A value indicating whether the uid list has been successfully processed</returns>
		/// <param name="theCodecFactory">The factor for doing the compression</param>
		protected bool ProcessUidList(Model.WorkQueue item, IDicomCodecFactory theCodecFactory)
		{
			StudyXml studyXml = LoadStudyXml(StorageLocation);

            int successfulProcessCount = 0;
			int totalCount = WorkQueueUidList.Count;
			foreach (WorkQueueUid sop in WorkQueueUidList)
			{
				if (sop.Failed)
					continue;

				if (CancelPending)
				{
					Platform.Log(LogLevel.Info,
					             "Received cancel request while compressing study {0}.  {1} instances successfully processed.",
					             StorageLocation.StudyInstanceUid, successfulProcessCount);

					return successfulProcessCount > 0;
				}

				if (ProcessWorkQueueUid(item, sop, studyXml, theCodecFactory))
					successfulProcessCount++;
			}

			if (successfulProcessCount > 0)
				Platform.Log(LogLevel.Info,"Completed compression of study {0}. {1} instances successfully processed.",
                    StorageLocation.StudyInstanceUid, successfulProcessCount);

				return successfulProcessCount > 0 && totalCount == successfulProcessCount;
		}
Exemplo n.º 9
0
 /// <summary>
 /// Set an <see cref="IDicomCodecFactory"/> for a transfer syntax, overriding the current value.
 /// </summary>
 /// <param name="syntax">The transfer syntax of the codec.</param>
 /// <param name="factory">The factory for the codec.</param>
 public static void SetCodec(TransferSyntax syntax, IDicomCodecFactory factory)
 {
     Dictionary[syntax] = factory;
 }
Exemplo n.º 10
0
        private bool ProcessWorkQueueUid(Model.WorkQueue item, WorkQueueUid sop, StudyXml studyXml, IDicomCodecFactory theCodecFactory)
        {
            Platform.CheckForNullReference(item, "item");
            Platform.CheckForNullReference(sop, "sop");
            Platform.CheckForNullReference(studyXml, "studyXml");

            if (!studyXml.Contains(sop.SeriesInstanceUid, sop.SopInstanceUid))
            {
                // Uid was inserted but not in the study xml.
                // Auto-recovery might have detect problem with that file and remove it from the study.
                // Assume the study xml has been corrected and ignore the uid.
                Platform.Log(LogLevel.Warn, "Skipping SOP {0} in series {1}. It is no longer part of the study.", sop.SopInstanceUid, sop.SeriesInstanceUid);

                // Delete it out of the queue
                DeleteWorkQueueUid(sop);
                return(true);
            }

            string basePath = Path.Combine(StorageLocation.GetStudyPath(), sop.SeriesInstanceUid);

            basePath = Path.Combine(basePath, sop.SopInstanceUid);
            string path;

            if (sop.Extension != null)
            {
                path = basePath + "." + sop.Extension;
            }
            else
            {
                path = basePath + ServerPlatform.DicomFileExtension;
            }

            try
            {
                ProcessFile(item, sop, path, studyXml, theCodecFactory);

                // WorkQueueUid has been deleted out by the processor

                return(true);
            }
            catch (Exception e)
            {
                if (e.InnerException != null && e.InnerException is DicomCodecUnsupportedSopException)
                {
                    Platform.Log(LogLevel.Warn, e, "Instance not supported for compressor: {0}.  Deleting WorkQueue entry for SOP {1}", e.Message, sop.SopInstanceUid);

                    item.FailureDescription = e.InnerException != null ? e.InnerException.Message : e.Message;

                    // Delete it out of the queue
                    DeleteWorkQueueUid(sop);

                    return(false);
                }
                Platform.Log(LogLevel.Error, e, "Unexpected exception when compressing file: {0} SOP Instance: {1}", path, sop.SopInstanceUid);
                item.FailureDescription = e.InnerException != null ? e.InnerException.Message : e.Message;

                sop.FailureCount++;

                UpdateWorkQueueUid(sop);

                return(false);
            }
        }
Exemplo n.º 11
0
        protected override void ProcessItem(Model.WorkQueue item)
        {
            LoadUids(item);

            if (WorkQueueUidList.Count == 0)
            {
                // No UIDs associated with the WorkQueue item.  Set the status back to idle
                PostProcessing(item,
                               WorkQueueProcessorStatus.Idle,
                               WorkQueueProcessorDatabaseUpdate.ResetQueueState);
                return;
            }


            XmlElement element = item.Data.DocumentElement;

            string syntax = element.Attributes["syntax"].Value;

            TransferSyntax compressSyntax = TransferSyntax.GetTransferSyntax(syntax);

            if (compressSyntax == null)
            {
                item.FailureDescription =
                    String.Format("Invalid transfer syntax in compression WorkQueue item: {0}", element.Attributes["syntax"].Value);
                Platform.Log(LogLevel.Error, "Error with work queue item {0}: {1}", item.GetKey(), item.FailureDescription);
                base.PostProcessingFailure(item, WorkQueueProcessorFailureType.Fatal);
                return;
            }

            if (Study == null)
            {
                item.FailureDescription =
                    String.Format("Compression item does not have a linked Study record");
                Platform.Log(LogLevel.Error, "Error with work queue item {0}: {1}", item.GetKey(), item.FailureDescription);
                base.PostProcessingFailure(item, WorkQueueProcessorFailureType.Fatal);
                return;
            }

            Platform.Log(LogLevel.Info,
                         "Compressing study {0} for Patient {1} (PatientId:{2} A#:{3}) on partition {4} to {5}",
                         Study.StudyInstanceUid, Study.PatientsName, Study.PatientId,
                         Study.AccessionNumber, ServerPartition.Description, compressSyntax.Name);

            IDicomCodecFactory[] codecs          = DicomCodecRegistry.GetCodecFactories();
            IDicomCodecFactory   theCodecFactory = null;

            foreach (IDicomCodecFactory codec in codecs)
            {
                if (codec.CodecTransferSyntax.Equals(compressSyntax))
                {
                    theCodecFactory = codec;
                    break;
                }
            }

            if (theCodecFactory == null)
            {
                item.FailureDescription = String.Format("Unable to find codec for compression: {0}", compressSyntax.Name);
                Platform.Log(LogLevel.Error, "Error with work queue item {0}: {1}", item.GetKey(), item.FailureDescription);
                base.PostProcessingFailure(item, WorkQueueProcessorFailureType.Fatal);
                return;
            }

            if (!ProcessUidList(item, theCodecFactory))
            {
                PostProcessingFailure(item, WorkQueueProcessorFailureType.NonFatal);
            }
            else
            {
                Platform.Log(LogLevel.Info,
                             "Completed Compressing study {0} for Patient {1} (PatientId:{2} A#:{3}) on partition {4} to {5}",
                             Study.StudyInstanceUid, Study.PatientsName, Study.PatientId,
                             Study.AccessionNumber, ServerPartition.Description, compressSyntax.Name);


                if (compressSyntax.LossyCompressed)
                {
                    UpdateStudyStatus(StorageLocation, StudyStatusEnum.OnlineLossy, compressSyntax);
                }
                else
                {
                    UpdateStudyStatus(StorageLocation, StudyStatusEnum.OnlineLossless, compressSyntax);
                }

                PostProcessing(item,
                               WorkQueueProcessorStatus.Pending,
                               WorkQueueProcessorDatabaseUpdate.None);                 // batch processed, not complete
            }
        }
Exemplo n.º 12
0
        protected void ProcessFile(Model.WorkQueue item, WorkQueueUid sop, string path, StudyXml studyXml, IDicomCodecFactory theCodecFactory)
        {
            DicomFile file = null;

            _instanceStats = new CompressInstanceStatistics();

            _instanceStats.ProcessTime.Start();

            // Use the command processor for rollback capabilities.
            using (ServerCommandProcessor processor = new ServerCommandProcessor("Processing WorkQueue Compress DICOM File"))
            {
                string modality = String.Empty;

                try
                {
                    file = new DicomFile(path);

                    _instanceStats.FileLoadTime.Start();
                    file.Load(DicomReadOptions.StorePixelDataReferences | DicomReadOptions.Default);
                    _instanceStats.FileLoadTime.End();

                    modality = file.DataSet[DicomTags.Modality].GetString(0, String.Empty);

                    FileInfo fileInfo = new FileInfo(path);
                    _instanceStats.FileSize = (ulong)fileInfo.Length;

                    // Get the Patients Name for processing purposes.
                    String patientsName = file.DataSet[DicomTags.PatientsName].GetString(0, "");

                    if (file.TransferSyntax.Equals(theCodecFactory.CodecTransferSyntax))
                    {
                        // Delete the WorkQueueUid item
                        processor.AddCommand(new DeleteWorkQueueUidCommand(sop));

                        // Do the actual processing
                        if (!processor.Execute())
                        {
                            Platform.Log(LogLevel.Warn, "Failure deleteing WorkQueueUid: {0} for SOP: {1}", processor.Description, file.MediaStorageSopInstanceUid);
                            Platform.Log(LogLevel.Warn, "Compression file that failed: {0}", file.Filename);
                        }
                        else
                        {
                            Platform.Log(LogLevel.Warn, "Skip compressing SOP {0}. Its current transfer syntax is {1}",
                                         file.MediaStorageSopInstanceUid, file.TransferSyntax.Name);
                        }
                    }
                    else
                    {
                        IDicomCodec codec = theCodecFactory.GetDicomCodec();

                        // Create a context for applying actions from the rules engine
                        var context = new ServerActionContext(file, StorageLocation.FilesystemKey, ServerPartition, item.StudyStorageKey);
                        context.CommandProcessor = processor;

                        var parms           = theCodecFactory.GetCodecParameters(item.Data);
                        var compressCommand =
                            new DicomCompressCommand(context.Message, theCodecFactory.CodecTransferSyntax, codec, parms);
                        processor.AddCommand(compressCommand);

                        var save = new SaveDicomFileCommand(file.Filename, file, false);
                        processor.AddCommand(save);

                        // Update the StudyStream object, must be done after compression
                        // and after the compressed image has been successfully saved
                        var insertStudyXmlCommand = new UpdateStudyXmlCommand(file, studyXml, StorageLocation);
                        processor.AddCommand(insertStudyXmlCommand);

                        // Delete the WorkQueueUid item
                        processor.AddCommand(new DeleteWorkQueueUidCommand(sop));

                        // Do the actual processing
                        if (!processor.Execute())
                        {
                            EventManager.FireEvent(this, new FailedUpdateSopEventArgs {
                                File = file, ServerPartitionEntry = context.ServerPartition, WorkQueueUidEntry = sop, WorkQueueEntry = WorkQueueItem, FileLength = (ulong)insertStudyXmlCommand.FileSize, FailureMessage = processor.FailureReason
                            });

                            _instanceStats.CompressTime.Add(compressCommand.CompressTime);
                            Platform.Log(LogLevel.Error, "Failure compressing command {0} for SOP: {1}", processor.Description, file.MediaStorageSopInstanceUid);
                            Platform.Log(LogLevel.Error, "Compression file that failed: {0}", file.Filename);
                            throw new ApplicationException("Unexpected failure (" + processor.FailureReason + ") executing command for SOP: " + file.MediaStorageSopInstanceUid, processor.FailureException);
                        }
                        _instanceStats.CompressTime.Add(compressCommand.CompressTime);
                        Platform.Log(ServerPlatform.InstanceLogLevel, "Compress SOP: {0} for Patient {1}", file.MediaStorageSopInstanceUid,
                                     patientsName);

                        EventManager.FireEvent(this, new UpdateSopEventArgs {
                            File = file, ServerPartitionEntry = context.ServerPartition, WorkQueueUidEntry = sop, WorkQueueEntry = WorkQueueItem, FileLength = (ulong)insertStudyXmlCommand.FileSize
                        });
                    }
                }
                catch (Exception e)
                {
                    EventManager.FireEvent(this, new FailedUpdateSopEventArgs {
                        File = file, ServerPartitionEntry = ServerPartition, WorkQueueUidEntry = sop, WorkQueueEntry = WorkQueueItem, FileLength = (ulong)new FileInfo(path).Length, FailureMessage = processor.FailureReason
                    });

                    Platform.Log(LogLevel.Error, e, "Unexpected exception when {0}.  Rolling back operation.",
                                 processor.Description);
                    processor.Rollback();

                    throw;
                }
                finally
                {
                    _instanceStats.ProcessTime.End();
                    _studyStats.AddSubStats(_instanceStats);

                    _studyStats.StudyInstanceUid = StorageLocation.StudyInstanceUid;
                    if (String.IsNullOrEmpty(modality) == false)
                    {
                        _studyStats.Modality = modality;
                    }

                    // Update the statistics
                    _studyStats.NumInstances++;
                }
            }
        }
Exemplo n.º 13
0
 /// <summary>
 /// Set an <see cref="IDicomCodecFactory"/> for a transfer syntax, overriding the current value.
 /// </summary>
 /// <param name="syntax">The transfer syntax of the codec.</param>
 /// <param name="factory">The factory for the codec.</param>
 public static void SetCodec(TransferSyntax syntax, IDicomCodecFactory factory)
 {
     Dictionary[syntax] = factory;
 }
Exemplo n.º 14
0
		/// <summary>
		/// Set an <see cref="IDicomCodecFactory"/> for a transfer syntax, overriding the current value.
		/// </summary>
		/// <param name="syntax">The transfer syntax of the codec.</param>
		/// <param name="factory">The factory for the codec.</param>
		public static void SetCodec(TransferSyntax syntax, IDicomCodecFactory factory)
		{
			if (factory != null) _dictionary[syntax] = factory;
			else _dictionary.Remove(syntax);
		}