/*******************************************************************************
 *  Copyright 2017-2018 Centre for Development of Advanced Computing(C-DAC), Pune
 *  
 * 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.
 *******************************************************************************/
package cdac.medinfo.sdk.dcm30_04.srtree;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

import cdac.medinfo.sdk.dcm30_04.baselibs.CodeMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.CodeSequenceMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.CodeSequenceMacroDependentItem;
import cdac.medinfo.sdk.dcm30_04.baselibs.CompositeObjectReferenceMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.ConceptCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ConceptNameCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ContentSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ContentSequenceItem;
import cdac.medinfo.sdk.dcm30_04.baselibs.DocumentContentMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.DocumentRelationshipMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.IconImageSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.IconImageSequenceItem;
import cdac.medinfo.sdk.dcm30_04.baselibs.ImagePixelMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.ImageReferenceMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.MeasuredValueSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.MeasuredValueSequenceItem;
import cdac.medinfo.sdk.dcm30_04.baselibs.MeasurementUnitsCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.NumericMeasurementMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.NumericValueQualifierCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ReferencedSOPSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ReferencedSOPSequenceItem;
import cdac.medinfo.sdk.dcm30_04.baselibs.SpatialCoordinatesMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.TemporalCoordinatesMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.WaveformReferenceMacro;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataElement;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDicomValue;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IItem;
import cdac.medinfo.sdk.dcm30_04.dicommodel.modules.SRDocumentContentModule;
import cdac.medinfo.sdk.dcm30_04.dicomstreams.DicomFileStream;
import cdac.medinfo.sdk.dcm30_04.enums.EnumContinuityOfContent;
import cdac.medinfo.sdk.dcm30_04.enums.EnumRelationshipType;
import cdac.medinfo.sdk.dcm30_04.enums.EnumValueType;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidSRDocumentException;
import cdac.medinfo.sdk.dcm30_04.exceptions.TreeStructureViolationException;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConfig;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConstants;
import cdac.medinfo.sdk.dcm30_04.utils.DicomLogger;
import cdac.medinfo.sdk.dcm30_04.utils.ICollectionIterator;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.ResourceBundleWrapper;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
/**
 *	This class helps to create Root of SRTree. Also provides API for serializing Document in the form of 
 *	MS Word Document and XML document. 
 */
public class SRDocument 
{
	/**
	 * Object of SRDocumentContentModule.
	 */
	private SRDocumentContentModule objSRDocumentContentModule;
	
	/**
	 * Boolean variable represents presence of Root in a document.
	 */
	boolean flag = false;

	/**
	 * Instantiate Object of SRDocument.
	 */
	public SRDocument()
	{

	}

	/**
	 * Retrieves the SRDocumentContentModule.
	 * @return objSRDocumentContentModule Object of SRDocumentContentModule.
	 */
	public SRDocumentContentModule getSRDocumentContentModule()
	{
		return objSRDocumentContentModule;
	}
	
	/**
	 * Returns the value for flag.
	 * @return boolean flag.
	 */
	private boolean isRootCreated()
	{
		return this.flag;
	}

	
	/**
	 * Creates the root node for SR Document tree with passed information filled in respective attributes 
	 * and with ReferencedContentItemIdentifier as 1.
	 * @param objDocumentContentModule object of SRDocumentContentModule.
	 * @param enumRelationshipType String value for Relationship Type.
	 * @param strCodeMeaning string for CodeMeaning which will be heading for the document.
	 * @param strCodeValue string for CodeValue.
	 * @param strCodeSchemeDesignator string value for CodeSchemeDesignator.
	 * @param enumContinuityOfContent object of EnumContinuityOfContent.
	 * @return object of SRNode.
	 */
	public SRNode createRoot(SRDocumentContentModule objDocumentContentModule,EnumRelationshipType enumRelationshipType,String strCodeMeaning, String strCodeValue, String strCodeSchemeDesignator,EnumContinuityOfContent enumContinuityOfContent)
	{
		if(isRootCreated() == true)
		{
			TreeStructureViolationException objTreeStructureViolationException = new TreeStructureViolationException();
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger objDicomLogger = DicomLogger.getLogger();
				objDicomLogger.log(objTreeStructureViolationException);
			}
			//Throwing InvalidSRDocumentException with objTreeStructureViolationException as a cause of it.
			throw new InvalidSRDocumentException(ResourceBundleWrapper.getValue("exceptions","SRTree.TreeStructureViolation",new Locale(DicomConfig.createInstance().getLocale())),objTreeStructureViolationException);
		}
		else
		{
			this.flag = true;
			this.objSRDocumentContentModule = objDocumentContentModule;
	
			//-----------  Get ContentSequenceMacro and add to DataSet since document suggests that
			//the SR Document Content Module consists of A DocumentContentMacro and then a DocumentRelationshipMacro
			DocumentContentMacro objDocumentContentMacroRoot = objDocumentContentModule.getDocumentContentMacro();
			objDocumentContentMacroRoot.setValueType(EnumValueType.CONTAINER);
			ConceptNameCodeSequence objNameCodeSequence = objDocumentContentMacroRoot.getConceptNameCodeSequence();
			CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItem = objNameCodeSequence.getNewItem();
	
			CodeSequenceMacro objCodeSequenceMacro = objCodeSequenceMacroDependentItem.getCodeSequenceMacro();
			objCodeSequenceMacro.setCodeMeaning(strCodeMeaning);
			objCodeSequenceMacro.setCodeValue(strCodeValue);
			objCodeSequenceMacro.setCodeSchemeDesignator(strCodeSchemeDesignator);
			objNameCodeSequence.addItem(objCodeSequenceMacroDependentItem);
	
			//----------Get Document Relationship Macro from module
			DocumentRelationshipMacro objDocumentRelationshipMacro = objDocumentContentModule.getDocumentRelationshipMacro();
	
			ContentSequence objContentSequenceRoot = objDocumentRelationshipMacro.getContentSequence();
			ContentSequenceItem objContentSequenceItem = objContentSequenceRoot.getNewItem();
	
			/**
			 * Sets The type of relationship between the (enclosing) Source Content Item and the
			 * Target Content Item.
			 */
			objContentSequenceItem.setRelationshipType(enumRelationshipType);
	
			//-----------  Get ConteneSequenceMacro and add to root's Content Sequence Item
			objDocumentContentMacroRoot = objContentSequenceItem.getDocumentContentMacro();
			objDocumentContentMacroRoot.setValueType(EnumValueType.CONTAINER);
			objNameCodeSequence = objDocumentContentMacroRoot.getConceptNameCodeSequence();
			objCodeSequenceMacroDependentItem = objNameCodeSequence.getNewItem();
	
			objCodeSequenceMacro = objCodeSequenceMacroDependentItem.getCodeSequenceMacro();
			objCodeSequenceMacro.setCodeMeaning(strCodeMeaning);
			objCodeSequenceMacro.setCodeValue(strCodeValue);
			objCodeSequenceMacro.setCodeSchemeDesignator(strCodeSchemeDesignator);
	
			objNameCodeSequence.addItem(objCodeSequenceMacroDependentItem);
			objDocumentContentMacroRoot.setContinuityOfContent(enumContinuityOfContent);
	
			/**
			 * setting ReferencedContentItemIdentifier for ROOT node which will alwasy be 1.
			 */
			int[] lArrReferencedContentItemIdentifierForRoot = {1};
			objContentSequenceItem.setReferencedContentItemIdentifier(lArrReferencedContentItemIdentifierForRoot);
	
			DocumentRelationshipMacro objDocumentRelationshipMacroOfRoot = objContentSequenceItem.getDocumentRelationshipMacro();
			@SuppressWarnings("unused")
			ContentSequence objContentSequence = objDocumentRelationshipMacroOfRoot.getContentSequence();
	
			objContentSequenceRoot.addItem(objContentSequenceItem);
	
			//this.objRootContentSequenceItem = objContentSequenceItem;
			//this.objRootContentSequence = objContentSequenceRoot;
	
			/**
			 * This will create a SRNode object with ContentSequenceItem which is ROOT node of a document.
			 */
			SRNode objNode = new SRNode(objContentSequenceItem);
	
			return objNode;
		}
	}

	/**
	 * creates the SR document in the form of doc file.
	 * @param objIDataSet Object of IDataSet.
	 * @param path  path where SR document will be kept.
	 * @return boolean value i. e. true or false.
	 */
	@SuppressWarnings("unchecked")
	public boolean serializeSRDoc(IDataSet objIDataSet, String strPath)throws IOException
	{
		// Fetching StudyInstanceUID for giving name to the SR document.
		String strStudyInstanceUID =  objIDataSet.getValue(0x0020,0x000D).toString();
		if(null==strStudyInstanceUID)
			strStudyInstanceUID =  objIDataSet.getValue(0x0008,0x0018).toString();
			
		
		File objFile = null;

		//If user dont provide its own path for storage take that path otherwise use default storage path. 
		if(strPath == null)				
			strPath = DicomConstants.DICOM_CSTORE_STORAGE_PATH;

		objFile = new File(strPath );
		objFile.mkdirs();

		if(!strPath.endsWith("/"));
		String strDocumentName = strPath + "/" + strStudyInstanceUID+".doc";

		objFile = new File(strDocumentName);

		// creating FileOutputStream object and setting it to the DicomFileStream.
		FileOutputStream objFileOutputStream = new FileOutputStream(objFile);
		DicomFileStream objDicomFileStream = new DicomFileStream();
		objDicomFileStream.setOutputStream(objFileOutputStream);

		/**
		 * Fetching Concept Name Code Sequence from DataSet.
		 */
		IDataElement objIDataElement1 = objIDataSet.getDataForTag(0x0040, 0xA043);
		IDicomValue objIDicomValue1 = objIDataElement1.getDicomValue();
		ConceptNameCodeSequence objConceptNameCodeSequence1= (ConceptNameCodeSequence)objIDicomValue1;

		/**
		 * getValue method will return Single Collection of Items of a sequence.
		 */			
		ISingleCollection<IItem> objSingleCollectionConceptNameCodeSequenceItem1 = (ISingleCollection<IItem>)objConceptNameCodeSequence1.getValue();

		/**
		 * Writing Heading of a SR Document, fetching value of Code Meaning from CodeSequenceMacroDependentItem.
		 * There will be single ConceptNameCodeSequenceItem will be present in ConceptNameCodeSequence.
		 */
		if(objSingleCollectionConceptNameCodeSequenceItem1 != null)
		{
			CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItem1 = (CodeSequenceMacroDependentItem)objSingleCollectionConceptNameCodeSequenceItem1.elementAt(0);
			if(objCodeSequenceMacroDependentItem1.contains(0x0008,0x0104))
			{
				//System.out.println(objCodeSequenceMacroDependentItem1.getValue(0x0008,0x0104).toString() + "\n");
				String objStrToWrite = "\t\t\t\t\t" + objCodeSequenceMacroDependentItem1.getValue(0x0008,0x0104).toString() + "\n";
				byte[] b_array = objStrToWrite.getBytes();
				objFileOutputStream.write(b_array);
			}
		}

		/**
		 * Fetching ContentSequence from DataSet.
		 */
		IDataElement objIDataElement = objIDataSet.getDataForTag(0x0040, 0xA730);
		IDicomValue objIDicomValue = objIDataElement.getDicomValue();
		ContentSequence objContentSequence = (ContentSequence)objIDicomValue;

		if(objContentSequence != null)
		{
			/**
			 *  Iterator for items of Content Sequence.
			 */
			ICollectionIterator<IItem> objContentSequenceIterator = objContentSequence.iterator();

			ContentSequenceItem objContentSequenceItem = null;

			/**
			 * String value of EnumValueType.
			 * It can be : 
			 * 1.  PNAME
			 * 2.  TEXT
			 * 3.  CONTAINER
			 * 4.  CODE
			 * 5.  COMPOSITE
			 * 6.  DATETIME
			 * 7.  DATE
			 * 8.  IMAGE
			 * 9.  NUM
			 * 10. TIME
			 * 11. UIDREF
			 * 12. WAVEFORM
			 * 13. SCOORD
			 * 14. TCOORD
			 */
			String strValueType = null;

			while(objContentSequenceIterator.hasNext())
			{
				objContentSequenceItem = (ContentSequenceItem)objContentSequenceIterator.next();

				/**
				 * Fetching DocumentContentMacro and DocumentRelationshipMacro from objContentSequenceItem.
				 */
				DocumentContentMacro objDocumentContentMacro = objContentSequenceItem.getDocumentContentMacro();
				DocumentRelationshipMacro objDocumentRelationshipMacro = objContentSequenceItem.getDocumentRelationshipMacro();

				/**
				 * Fetching ValueType and ConceptNameCodeSequence from DocumentContentMacro.
				 */
				strValueType = objDocumentContentMacro.getValueType();
				ConceptNameCodeSequence objConceptNameCodeSequence = objDocumentContentMacro.getConceptNameCodeSequence();

				/**
				 *  Getting Item Collection of ConceptNameCodeSequence.
				 *  According to attribute information of DocumentContentMacro of SRDocumentContent this sequence will have single item.
				 */
				ISingleCollection<IItem> objSingleCollectionConceptNameCodeSequenceItem = (ISingleCollection<IItem>)objConceptNameCodeSequence.getValue();

				if(objSingleCollectionConceptNameCodeSequenceItem != null)
				{
					CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItem = (CodeSequenceMacroDependentItem)objSingleCollectionConceptNameCodeSequenceItem.elementAt(0);

					/**
					 * if strValueType is CONTAINER
					 */
					if(EnumValueType.CONTAINER.getValue().equals(strValueType))
					{
						Display(objDicomFileStream, objCodeSequenceMacroDependentItem, objDocumentRelationshipMacro);
						objDicomFileStream.close();
					}
				}
			}
		}
		return true;
	}



	/**
	 * Writes the contents of CONTAINER to the SRDoc by traversing through its ContentSequence.
	 * @param objDicomFileStream Object of DicomFileStream Object of CodeSequenceMacroDependentItem.
	 * @param objCodeSequenceMacroDependentItem Object of DocumentRelationshipMacro.
	 * @param objDocumentRelationshipMacro.
	 * @throws IOException.
	 */
	@SuppressWarnings("unchecked")
	private void Display(DicomFileStream objDicomFileStream , CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItem, DocumentRelationshipMacro objDocumentRelationshipMacro)throws IOException
	{
		String objStrToWrite = null;
		byte[] b_array = null;

		if(objCodeSequenceMacroDependentItem.contains(0x0008,0x0104))
		{
//			/**
//			* Writing Container heading.
//			*/
//			//System.out.println(objCodeSequenceMacroDependentItem.getValue(0x0008,0x0104).toString() + "\n");
//			objStrToWrite =  "\n\n" + objCodeSequenceMacroDependentItem.getValue(0x0008,0x0104).toString();
//			b_array = objStrToWrite.getBytes();
//			objDicomFileStream.writeChars(b_array);

			/**
			 * Container will have one or more ContentSequence Item.
			 */
			ContentSequence objContentSequenceForInnerSQ = null;
			if(objDocumentRelationshipMacro.contains(0x0040,0xA730))	// ContentSequence.
			{
				IDataElement objDataElement = objDocumentRelationshipMacro.getDataElement(0x0040,0xA730);
				IDicomValue objIDicomValueForInnerSQ = objDataElement.getDicomValue();
				objContentSequenceForInnerSQ = (ContentSequence)objIDicomValueForInnerSQ;

			}
			{	// TRIAL CODE
				//ISingleCollection<IItem> objContentSequenceItemColl = (ISingleCollection<IItem>)objContentSequenceForInnesSQ.getValue();

				{
					//System.out.println(objContentSequenceItemColl.size());
				}
			}
			/**
			 * Iterator over ContentSequenceItems of ContentSequence for Container
			 */
			ICollectionIterator<IItem> objCollectionIteratorForInnerItems = objContentSequenceForInnerSQ.iterator();

			ContentSequenceItem objContentSequenceItemForInner=null;

			while(objCollectionIteratorForInnerItems.hasNext())
			{
				/**
				 * Fetching item of a ContentSequence.
				 */
				objContentSequenceItemForInner = (ContentSequenceItem)objCollectionIteratorForInnerItems.next();

				/**
				 * Fetching DocumentContentMacro from ContentSequenceItem to write information like Heading
				 */
				DocumentContentMacro objDocumentContentMacro = objContentSequenceItemForInner.getDocumentContentMacro();


				//int []arrIdentifier = objContentSequenceItemForInner.getReferencedContentItemIdentifier();
				//	addTabs(arrIdentifier);
//				int ilen = arrIdentifier.length;
//				for(int i = 0; i<ilen; i++)
//				{
//				objStrToWrite = "\t";
//				b_array = objStrToWrite.getBytes();
//				objDicomFileStream.writeChars(b_array);
//				}
				objStrToWrite = "\n";
				b_array = objStrToWrite.getBytes();
				objDicomFileStream.writeChars(b_array);

				if(objDocumentContentMacro != null)
				{
					CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItemForInner = null;
					if(objDocumentContentMacro.contains(0x0040, 0xA043))	//ConceptNameCodeSequence
					{
						ConceptNameCodeSequence objConceptNameCodeSequenceForInner = objDocumentContentMacro.getConceptNameCodeSequence();
						ISingleCollection<IItem> objSingleCollectionConceptNameCodeSequenceItemForInner = (ISingleCollection<IItem>)objConceptNameCodeSequenceForInner.getValue();
						objCodeSequenceMacroDependentItemForInner = (CodeSequenceMacroDependentItem)objSingleCollectionConceptNameCodeSequenceItemForInner.elementAt(0);

						if(objCodeSequenceMacroDependentItemForInner.contains(0x0008,0x0104))
						{
							/**
							 * Writing Heading for Inner Node(Child Node).
							 */
							//System.out.println(objCodeSequenceMacroDependentItem.getValue(0x0008,0x0104).toString() + " : " + objDocumentContentMacro.getPersonName().toString() + "\n");
							objStrToWrite = objCodeSequenceMacroDependentItemForInner.getValue(0x0008,0x0104).toString() + " : " ;
							b_array = objStrToWrite.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
					}
					if(objDocumentContentMacro.contains(0x0040, 0xA040))	//ValueType
					{
						/**
						 * If valueType is PNAME for InnerItem(Child Node).
						 */
						if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.PNAME.getValue()))
						{
							objStrToWrite = " " + objDocumentContentMacro.getPersonName().toString() + "\n";
							b_array = objStrToWrite.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
						/**
						 * If valueType is TEXT for InnerItem(Child Node).
						 */
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.TEXT.getValue()))
						{
							//int []arrIdentifier = objContentSequenceItemForInner.getReferencedContentItemIdentifier();
							//addTabs(arrIdentifier);

							objStrToWrite = "\n" + objDocumentContentMacro.getTextValue().toString() + "\n";
							b_array = objStrToWrite.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.DATETIME.getValue()))
						{
							//addTabs(arrIdentifier);

							objStrToWrite = "\n" + objDocumentContentMacro.getDateTime() + "\n";
							b_array = objStrToWrite.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.DATE.getValue()))
						{
							//addTabs(arrIdentifier);

							objStrToWrite = "\n" + objDocumentContentMacro.getDate() + "\n";
							b_array = objStrToWrite.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.TIME.getValue()))
						{
							//addTabs(arrIdentifier);

							objStrToWrite = "\n" + objDocumentContentMacro.getTime() + "\n";
							b_array = objStrToWrite.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.UIDREF.getValue()))
						{
							//addTabs(arrIdentifier);

							objStrToWrite = "\n" + objDocumentContentMacro.getUID() + "\n";
							b_array = objStrToWrite.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
						/**
						 * If valueType is CODE for InnerItem(Child Node).
						 */
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.CODE.getValue()))
						{
							//addTabs(arrIdentifier);

							CodeMacro objCodeMacro = objDocumentContentMacro.getCodeMacro();

							ConceptCodeSequence objConceptCodeSequence = objCodeMacro.getConceptCodeSequence();

							ISingleCollection<CodeSequenceMacroDependentItem> objCollection = (ISingleCollection<CodeSequenceMacroDependentItem>)objConceptCodeSequence.getValue();

							ICollectionIterator<CodeSequenceMacroDependentItem> objCollectionIterator = objCollection.iterator();
							while(objCollectionIterator.hasNext())
							{
								CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItem2 = objCollectionIterator.next();
								CodeSequenceMacro objCodeSequenceMacro = objCodeSequenceMacroDependentItem2.getCodeSequenceMacro();
								objStrToWrite = "\n" + objCodeSequenceMacro.getCodeMeaning();
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);
								if(null!= objCodeSequenceMacro.getSNOMEDCTID())
									{
										objStrToWrite = "\n" + "SNOMED CT ID :"+objCodeSequenceMacro.getSNOMEDCTID();
										b_array = objStrToWrite.getBytes();
										objDicomFileStream.writeChars(b_array);
									}
								
//								objStrToWrite = "\n" + " Code Scheme Designator - " +objCodeSequenceMacro.getCodeSchemeDesignator() + "\n";
//								b_array = objStrToWrite.getBytes();
//								objDicomFileStream.writeChars(b_array);
							}
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.COMPOSITE.getValue()))
						{
							//addTabs(arrIdentifier);

							CompositeObjectReferenceMacro objCompositeObjectReferenceMacro = objDocumentContentMacro.getCompositeObjectReferenceMacro();
							ReferencedSOPSequence objReferencedSOPSequence = objCompositeObjectReferenceMacro.getReferencedSOPSequence();
							ISingleCollection<ReferencedSOPSequenceItem> objSingleCollection = (ISingleCollection<ReferencedSOPSequenceItem>)objReferencedSOPSequence.getValue();

							for (ReferencedSOPSequenceItem item : objSingleCollection) 
							{
								objStrToWrite = "\n Referenced SOP Class UID : " + item.getSOPInstanceReferenceMacro().getReferencedSOPClassUID();
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);

								objStrToWrite = "\n Referenced SOP Instance UID : " + item.getSOPInstanceReferenceMacro().getReferencedSOPInstanceUID() + "\n";
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);
							}
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.NUM.getValue()))
						{
							//addTabs(arrIdentifier);

							NumericMeasurementMacro objNumericMeasurementMacro = objDocumentContentMacro.getNumericMeasurementMacro();
							MeasuredValueSequence objMeasuredValueSequence = objNumericMeasurementMacro.getMeasuredValueSequence();
							ISingleCollection<MeasuredValueSequenceItem> objSingleCollection = (ISingleCollection<MeasuredValueSequenceItem>)objMeasuredValueSequence.getValue();

							for (MeasuredValueSequenceItem item : objSingleCollection) 
							{
								String [] arrStrToWrite = item.getNumericValue();
								int ilength = arrStrToWrite.length;



								//Retrieves MeasurementUnitsCodeSequence
								MeasurementUnitsCodeSequence objMeasurementUnitsCodeSequence = item.getMeasurementUnitsCodeSequence();
								ISingleCollection<CodeSequenceMacroDependentItem> objCollection = (ISingleCollection<CodeSequenceMacroDependentItem>)objMeasurementUnitsCodeSequence.getValue();

								for(CodeSequenceMacroDependentItem itemCSMDI : objCollection)
								{
									CodeSequenceMacro objCodeSequenceMacro = itemCSMDI.getCodeSequenceMacro();

//									objStrToWrite = "\n" + objCodeSequenceMacro.getCodeMeaning();
//									b_array = objStrToWrite.getBytes();
//									objDicomFileStream.writeChars(b_array);

//									objStrToWrite = "\n" + objCodeSequenceMacro.getCodeValue();
//									b_array = objStrToWrite.getBytes();
//									objDicomFileStream.writeChars(b_array);

									for(int i=0; i < ilength ;i++)
									{
										objStrToWrite = "\n" + arrStrToWrite[i] + objCodeSequenceMacro.getCodeMeaning() + "\n";
										b_array = objStrToWrite.getBytes();
										objDicomFileStream.writeChars(b_array);
									}
								}

								//Retrieves Numeric Value Qualifier Code Sequence
								NumericValueQualifierCodeSequence objNumericValueQualifierCodeSequence = objNumericMeasurementMacro.getNumericValueQualifierCodeSequence();
								ISingleCollection<CodeSequenceMacroDependentItem> objCollection2 = (ISingleCollection<CodeSequenceMacroDependentItem>)objNumericValueQualifierCodeSequence.getValue();

								for(CodeSequenceMacroDependentItem itemCSMDI : objCollection2)
								{
									CodeSequenceMacro objCodeSequenceMacro = itemCSMDI.getCodeSequenceMacro();

									objStrToWrite = "\n" + objCodeSequenceMacro.getCodeMeaning();
									b_array = objStrToWrite.getBytes();
									objDicomFileStream.writeChars(b_array);

									objStrToWrite = "\n" + objCodeSequenceMacro.getCodeValue() + "\n";
									b_array = objStrToWrite.getBytes();
									objDicomFileStream.writeChars(b_array);
								}
							}
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.WAVEFORM.getValue()))
						{
							WaveformReferenceMacro objWaveformReferenceMacro = objDocumentContentMacro.getWaveformReferenceMacro();
							CompositeObjectReferenceMacro objCompositeObjectReferenceMacro = objWaveformReferenceMacro.getCompositeObjectReferenceMacro();

							ReferencedSOPSequence objReferencedSOPSequence = objCompositeObjectReferenceMacro.getReferencedSOPSequence();
							ISingleCollection<ReferencedSOPSequenceItem> objSingleCollection = (ISingleCollection<ReferencedSOPSequenceItem>)objReferencedSOPSequence.getValue();

							for (ReferencedSOPSequenceItem item : objSingleCollection) 
							{
								objStrToWrite = "\n Referenced SOP Class UID - " + item.getSOPInstanceReferenceMacro().getReferencedSOPClassUID();
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);

								objStrToWrite = "\n Referenced SOP Instance UID - " + item.getSOPInstanceReferenceMacro().getReferencedSOPInstanceUID();
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);
							}

							// Retrieving value for Referenced Waveform Channels
							short [] sharrWRMC = objWaveformReferenceMacro.getReferencedWaveformChannels();
							String strVal = "\n Referenced Waveform Channels - ";
							
							strVal = strVal + shortArrayToString(sharrWRMC) + "\n";
							b_array = strVal.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.SCOORD.getValue()))
						{
							SpatialCoordinatesMacro objSpatialCoordinatesMacro = objDocumentContentMacro.getSpatialCoordinatesMacro();

							float []arrflGraphicData = objSpatialCoordinatesMacro.getGraphicData();

							String strVal = "\n Graphic Data - ";
							
							strVal = strVal + floatArrayToString(arrflGraphicData);
							b_array = strVal.getBytes();
							objDicomFileStream.writeChars(b_array);

							strVal = "\n Graphic Type - " + objSpatialCoordinatesMacro.getGraphicType() + "\n";
							b_array = strVal.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.TCOORD.getValue()))
						{
							TemporalCoordinatesMacro objTemporalCoordinatesMacro = objDocumentContentMacro.getTemporalCoordinatesMacro();

							//Get Referenced Date Time 
							String []arr = objTemporalCoordinatesMacro.getReferencedDatetime();

							String strVal = "\n Referenced Datetime - ";
							strVal = strVal + stringArrayToString(arr);
							b_array = strVal.getBytes();
							objDicomFileStream.writeChars(b_array);
							
							//Get Referenced Sample Position.
							int[] larr = objTemporalCoordinatesMacro.getReferencedSamplePositions();
							strVal = "\n Referenced Sample Positions - ";
							strVal = strVal + intArrayToString(larr);
							b_array = strVal.getBytes();
							objDicomFileStream.writeChars(b_array);

							//Get Referenced Date Time 
							arr = objTemporalCoordinatesMacro.getReferencedTimeOffsets();
							strVal = "\n Referenced Time Offset - ";
							strVal = strVal + stringArrayToString(arr);
							b_array = strVal.getBytes();
							objDicomFileStream.writeChars(b_array);

							//Get Temporal Range Type
							strVal = "\n Temporal Range Type - " + objTemporalCoordinatesMacro.getTemporalRangeType() + "\n";
							b_array = strVal.getBytes();
							objDicomFileStream.writeChars(b_array);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.IMAGE.getValue()))
						{
							ImageReferenceMacro objImageReferenceMacro = objDocumentContentMacro.getImageReferenceMacro();

							//ReferencedSOPSequence in CompositeObjectReferenceMacro
							CompositeObjectReferenceMacro objCompositeObjectReferenceMacro = objImageReferenceMacro.getCompositeObjectReferenceMacro();
							ReferencedSOPSequence objReferencedSOPSequence = objCompositeObjectReferenceMacro.getReferencedSOPSequence();
							ISingleCollection<ReferencedSOPSequenceItem> objSingleCollection = (ISingleCollection<ReferencedSOPSequenceItem>)objReferencedSOPSequence.getValue();

							for (ReferencedSOPSequenceItem item : objSingleCollection) 
							{
								objStrToWrite = "\n Referenced SOP Class UID - " + item.getSOPInstanceReferenceMacro().getReferencedSOPClassUID();
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);

								objStrToWrite = "\n Referenced SOP Instance UID - " + item.getSOPInstanceReferenceMacro().getReferencedSOPInstanceUID();
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);
							}

							// Referenced Fame Number
							String [] strarrRefFramNo = objImageReferenceMacro.getReferencedFrameNumber();
							String strVal = "\n Referenced Frame Number - ";
							strVal = strVal + stringArrayToString(strarrRefFramNo);
							b_array = strVal.getBytes();
							objDicomFileStream.writeChars(b_array);

							//ReferencedSOPSequence in Image Referenced Macro
							ReferencedSOPSequence objReferencedSOPSequence1 = objImageReferenceMacro.getReferencedSOPSequence();
							ISingleCollection<ReferencedSOPSequenceItem> objSingleCollection1 = (ISingleCollection<ReferencedSOPSequenceItem>)objReferencedSOPSequence1.getValue();

							for (ReferencedSOPSequenceItem item : objSingleCollection1) 
							{
								objStrToWrite = "\n Referenced SOP Class UID - " + item.getSOPInstanceReferenceMacro().getReferencedSOPClassUID();
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);

								objStrToWrite = "\n Referenced SOP Instance UID - " + item.getSOPInstanceReferenceMacro().getReferencedSOPInstanceUID();
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);
							}

							//Get Icon Image Sequence
							IconImageSequence objIconImageSequence = objImageReferenceMacro.getIconImageSequence();
							ISingleCollection<IconImageSequenceItem> objcollIIS = (SingleCollection<IconImageSequenceItem>)objIconImageSequence.getValue();
							for(IconImageSequenceItem item : objcollIIS)
							{
								ImagePixelMacro objImagePixelMacro = item.getImagePixelMacro();
								short shBitsAllocated = objImagePixelMacro.getBitsAllocated();
								objStrToWrite = "\n Bits Allocated - " + shBitsAllocated;
								b_array = objStrToWrite.getBytes();
								objDicomFileStream.writeChars(b_array);
							}
						}
						/**
						 * If valueType is CONTAINER for InnerItem(Child Node).
						 */
//						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase("CONTAINER"))
//						{
//						/**
//						* Writing Container heading.
//						*/
//						ConceptNameCodeSequence objConceptNameCodeSequenceForInner = objDocumentContentMacro.getConceptNameCodeSequence();
//						ISingleCollection<IItem> objSingleCollectionConceptNameCodeSequenceItemForInner = (ISingleCollection<IItem>)objConceptNameCodeSequenceForInner.getValue();
//						objCodeSequenceMacroDependentItemForInner = (CodeSequenceMacroDependentItem)objSingleCollectionConceptNameCodeSequenceItemForInner.elementAt(0);

//						if(objCodeSequenceMacroDependentItemForInner.contains(0x0008,0x0104))
//						{
//						/**
//						* Writing Heading for Node.
//						*/
//						//System.out.println(objCodeSequenceMacroDependentItem.getValue(0x0008,0x0104).toString() + " : " + objDocumentContentMacro.getPersonName().toString() + "\n");
//						objStrToWrite = "\n\n" + objCodeSequenceMacroDependentItemForInner.getValue(0x0008,0x0104).toString() + " : " ;
//						b_array = objStrToWrite.getBytes();
//						objDicomFileStream.writeChars(b_array);
//						}
//						}

						/**
						 * This part of code retrieves the Document Relationship macro, if the Content Sequence present in 
						 * Doc Relationship Macro for this ContentSequenceItem has another ContentSequence Item in it, 
						 * then it will again call Display method to serialize that Item too.
						 * For eg. If CODE type of node itself contains another say, PNAME type of node, then it will serialize
						 * that PNAME type of node.
						 */
						DocumentRelationshipMacro objDocumentRelationshipMacroToGetInnerContentSQ = objContentSequenceItemForInner.getDocumentRelationshipMacro();
						Display(objDicomFileStream, objCodeSequenceMacroDependentItemForInner, objDocumentRelationshipMacroToGetInnerContentSQ);
					}
				}
			}
		}
	}


	/**
	 * Creates the SR document in the form of XML file.
	 * @param objIDataSet Object of IDataSet.
	 * @param path  Complete path with name where SR document will be kept.
	 * @return boolean value i. e. true or false.
	 */
	public boolean serializeXMLSRDoc(IDataSet objIDataSet,String strPath)throws IOException, ParserConfigurationException
	{
		File objFile = null;

		//Fetching StudyInstanceUID for giving name to the SR document.
		String strStudyInstanceUID = objIDataSet.getValue(0x0020,0x000D).toString();

		//If user dont provide its own path for storage take that path otherwise use default storage path. 
		if(strPath == null)				
			strPath = DicomConstants.DICOM_CSTORE_STORAGE_PATH;

		objFile = new File(strPath );
		objFile.mkdirs();

		if(!strPath.endsWith("/"));
		String strDocumentName = strPath + "/" + strStudyInstanceUID+".xml";

		objFile = new File(strDocumentName);

		//Creating Document object
		Document dom = null;

		//get an instance of factory
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

		//get an instance of builder
		DocumentBuilder db = dbf.newDocumentBuilder();

		//create an instance of DOM
		dom = db.newDocument();

		// Root Element
		Element rootEle = null;

		// Starts the process of XML Serialization which can throw IOException
		startXMLSerialization(objIDataSet, dom, rootEle);

		//print
		OutputFormat format = new OutputFormat(dom);
		//format.setIndenting(true);

		//to generate output to console use this serializer
		XMLSerializer serializer = new XMLSerializer(System.out, format);

		//to generate a file output use fileoutputstream instead of system.out
		serializer = new XMLSerializer(new FileOutputStream(new File(strDocumentName)), format);

		serializer.serialize(dom);
		return true;
	}

	/**
	 * Starts the serialization of data set in the form of XML doc.
	 * @param objIDataSet Object of IDataset which is to be serialized in the form of XML document.
	 * @param dom Object of Document.
	 * @param rootEle Object of Element represents Root of XML document.
	 * @throws IOException .
	 */
	@SuppressWarnings("unchecked")
	private void startXMLSerialization(IDataSet objIDataSet,Document dom ,Element rootEle)throws IOException
	{
		/**
		 * Fetching Concept Name Code Sequence from DataSet.
		 */
		IDataElement objIDataElement1 = objIDataSet.getDataForTag(0x0040, 0xA043);
		IDicomValue objIDicomValue1 = objIDataElement1.getDicomValue();
		ConceptNameCodeSequence objConceptNameCodeSequence1= (ConceptNameCodeSequence)objIDicomValue1;

		/**
		 * getValue method will return Single Collection of Items of a sequence.
		 */

		ISingleCollection<IItem> objSingleCollectionConceptNameCodeSequenceItem1 = (ISingleCollection<IItem>)objConceptNameCodeSequence1.getValue();


		/**
		 * Writing Heading of a SR Document, fetching value of Code Meaning from CodeSequenceMacroDependentItem.
		 * There will be single ConceptNameCodeSequenceItem will be present in ConceptNameCodeSequence.
		 */
		if(objSingleCollectionConceptNameCodeSequenceItem1 != null)
		{
			CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItem1 = (CodeSequenceMacroDependentItem)objSingleCollectionConceptNameCodeSequenceItem1.elementAt(0);
			if(objCodeSequenceMacroDependentItem1.contains(0x0008,0x0104))
			{
				//System.out.println(objCodeSequenceMacroDependentItem1.getValue(0x0008,0x0104).toString() + "\n");
				String objStrToWrite = objCodeSequenceMacroDependentItem1.getValue(0x0008,0x0104).toString();
				//create the root element <Document Heading>

				rootEle = dom.createElement("DOCUMENT");
				rootEle.setAttribute("type", objStrToWrite);
				dom.appendChild(rootEle);
			}
		}

		/**
		 * Fatching ContentSequence from DataSet.
		 */
		IDataElement objIDataElement = objIDataSet.getDataForTag(0x0040, 0xA730);
		IDicomValue objIDicomValue = objIDataElement.getDicomValue();
		ContentSequence objContentSequence = (ContentSequence)objIDicomValue;

		if(objContentSequence != null)
		{
			/**
			 *  Iterator for items of Content Sequence.
			 */
			ICollectionIterator<IItem> objContentSequenceIterator = objContentSequence.iterator();

			ContentSequenceItem objContentSequenceItem = null;

			/**
			 * String value of EnumValueType.
			 * It can be : 
			 * 1.  PNAME
			 * 2.  TEXT
			 * 3.  CONTAINER
			 * 4.  CODE
			 * 5.  COMPOSITE
			 * 6.  DATETIME
			 * 7.  DATE
			 * 8.  IMAGE
			 * 9.  NUM
			 * 10. TIME
			 * 11. UIDREF
			 * 12. WAVEFORM
			 * 13. SCOORD
			 * 14. TCOORD
			 */
			String strValueType = null;

			while(objContentSequenceIterator.hasNext())
			{
				objContentSequenceItem = (ContentSequenceItem)objContentSequenceIterator.next();

				/**
				 * Fetching DocumentContentMacro and DocumentRelationshipMacro from objContentSequenceItem.
				 */
				DocumentContentMacro objDocumentContentMacro = objContentSequenceItem.getDocumentContentMacro();
				DocumentRelationshipMacro objDocumentRelationshipMacro = objContentSequenceItem.getDocumentRelationshipMacro();

				/**
				 * Fetching ValueType and ConceptNameCodeSequence from DocumentContentMacro.
				 */
				strValueType = objDocumentContentMacro.getValueType();
				ConceptNameCodeSequence objConceptNameCodeSequence = objDocumentContentMacro.getConceptNameCodeSequence();

				/**
				 *  Getting Item Collection of ConceptNameCodeSequence.
				 *  According to attribute information of DocumentContentMacro of SRDocumentContent this sequence will have single item.
				 */
				ISingleCollection<IItem> objSingleCollectionConceptNameCodeSequenceItem = (ISingleCollection<IItem>)objConceptNameCodeSequence.getValue();

				if(objSingleCollectionConceptNameCodeSequenceItem != null)
				{
					CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItem = (CodeSequenceMacroDependentItem)objSingleCollectionConceptNameCodeSequenceItem.elementAt(0);

					/**
					 * if strValueType is CONTAINER
					 */
					if(EnumValueType.CONTAINER.getValue().equals(strValueType))
					{
						if(objDocumentRelationshipMacro != null)
							serializeXMLNode(dom, rootEle, objCodeSequenceMacroDependentItem, objDocumentRelationshipMacro);
					}
				}
			}
		}
	}

	/**
	 * Serializes each node of SR doc in the form of XML doc.
	 * @param dom Object of Document.
	 * @param rootEle Object of Element represents Root of XML document.
	 * @param objCodeSequenceMacroDependentItem Object of CodeSequenceMacroDependentItem.
	 * @param objDocumentRelationshipMacro Object of DocumentRelationshipMacro.
	 * @throws IOException.
	 */
	@SuppressWarnings("unchecked")
	private void serializeXMLNode(Document dom ,Element rootEle, CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItem, DocumentRelationshipMacro objDocumentRelationshipMacro)throws IOException
	{

		String strCodeValue = null;
		String strCodingSchemeDesignator = null;
		String strCodeMeaning = null;
		String strSNOMEDCTID = null ;

		if(objCodeSequenceMacroDependentItem.contains(0x0008,0x0104))
		{
			/**
			 * Container will have one or more ContentSequence Item.
			 */
			ContentSequence objContentSequenceForInnerSQ = null;
			if(objDocumentRelationshipMacro.contains(0x0040,0xA730))	// ContentSequence.
			{
				IDataElement objDataElement = objDocumentRelationshipMacro.getDataElement(0x0040,0xA730);
				IDicomValue objIDicomValueForInnerSQ = objDataElement.getDicomValue();
				objContentSequenceForInnerSQ = (ContentSequence)objIDicomValueForInnerSQ;

			}

			/**
			 * Iteratoe over ContentSequenceItems of ContentSequence for Container
			 */
			ICollectionIterator<IItem> objCollectionIteratorForInnerItems = objContentSequenceForInnerSQ.iterator();

			ContentSequenceItem objContentSequenceItemForInner=null;

			// Element which will be added in its parent node.
			Element ele = null;
						
			while(objCollectionIteratorForInnerItems.hasNext())
			{
				/**
				 * Fetching item of a ContentSequence.
				 */
				objContentSequenceItemForInner = (ContentSequenceItem)objCollectionIteratorForInnerItems.next();


				// Get Relationship Type
				String strRelationshipType = objContentSequenceItemForInner.getRelationshipType();

				// Get Referenced Content Item Identifier
				int [] identifier = objContentSequenceItemForInner.getReferencedContentItemIdentifier();
				String strIdentifier = intArrayToString(identifier);

				/**
				 * Fetching DocumentContentMacro from ContentSequenceItem to write information like Heading
				 */
				DocumentContentMacro objDocumentContentMacro = objContentSequenceItemForInner.getDocumentContentMacro();

				if(objDocumentContentMacro != null)
				{
					CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItemForInner = null;
					if(objDocumentContentMacro.contains(0x0040, 0xA043))	//ConceptNameCodeSequence
					{
						ConceptNameCodeSequence objConceptNameCodeSequenceForInner = objDocumentContentMacro.getConceptNameCodeSequence();
						ISingleCollection<IItem> objSingleCollectionConceptNameCodeSequenceItemForInner = (ISingleCollection<IItem>)objConceptNameCodeSequenceForInner.getValue();
						objCodeSequenceMacroDependentItemForInner = (CodeSequenceMacroDependentItem)objSingleCollectionConceptNameCodeSequenceItemForInner.elementAt(0);

						if(objCodeSequenceMacroDependentItemForInner.contains(0x0008,0x0104))
						{
							/**
							 * Getting CM,CV,CSD.
							 */
							//System.out.println(objCodeSequenceMacroDependentItem.getValue(0x0008,0x0104).toString() + " : " + objDocumentContentMacro.getPersonName().toString() + "\n");
							strCodeMeaning = objCodeSequenceMacroDependentItemForInner.getValue(0x0008,0x0104).toString();
							strCodeValue = objCodeSequenceMacroDependentItemForInner.getValue(0x0008,0x0100).toString();
							strCodingSchemeDesignator = objCodeSequenceMacroDependentItemForInner.getValue(0x0008,0x0102).toString();
							if(strSNOMEDCTID!=null)
							strSNOMEDCTID =objCodeSequenceMacroDependentItemForInner.getValue(0x0009, 0x0009).toString();
						}
					}
					
					if(objDocumentContentMacro.contains(0x0040, 0xA040))	//ValueType
					{
						String strValue = null;
						
						
						/**
						 * If valueType is PNAME for InnerItem(Child Node).
						 */
						if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.PNAME.getValue()))
						{
							strValue = objDocumentContentMacro.getPersonName();
							//Adding PNAME Type of Node
							ele = getSRElement(dom,EnumValueType.PNAME.getValue(),strIdentifier,strRelationshipType,strCodeMeaning,strCodeValue,strCodingSchemeDesignator,strValue);
							rootEle.appendChild(ele);
						}
						/**
						 * If valueType is TEXT for InnerItem(Child Node).
						 */
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.TEXT.getValue()))
						{
							strValue = objDocumentContentMacro.getTextValue();
							//Adding TEXT Type of Node
							ele = getSRElementSNMD(dom,EnumValueType.TEXT.getValue(),strIdentifier,strRelationshipType,strCodeMeaning,strCodeValue,strCodingSchemeDesignator,strValue,strSNOMEDCTID);
							rootEle.appendChild(ele);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.DATETIME.getValue()))
						{
							strValue = objDocumentContentMacro.getDateTime();
							//Adding DATETIME Type of Node
							ele = getSRElement(dom,EnumValueType.DATETIME.getValue(),strIdentifier,strRelationshipType,strCodeMeaning,strCodeValue,strCodingSchemeDesignator,strValue);
							rootEle.appendChild(ele);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.DATE.getValue()))
						{
							strValue = objDocumentContentMacro.getDate();
							//Adding DATE Type of Node
							ele = getSRElement(dom,EnumValueType.DATE.getValue(),strIdentifier,strRelationshipType,strCodeMeaning,strCodeValue,strCodingSchemeDesignator,strValue);
							rootEle.appendChild(ele);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.TIME.getValue()))
						{
							strValue = objDocumentContentMacro.getTime();
							//Adding TIME Type of Node
							ele = getSRElement(dom,EnumValueType.TIME.getValue(),strIdentifier,strRelationshipType,strCodeMeaning,strCodeValue,strCodingSchemeDesignator,strValue);
							rootEle.appendChild(ele);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.UIDREF.getValue()))
						{
							strValue = objDocumentContentMacro.getUID();
							//Adding UIDREF Type of Node
							ele = getSRElement(dom,EnumValueType.UIDREF.getValue(),strIdentifier,strRelationshipType,strCodeMeaning,strCodeValue,strCodingSchemeDesignator,strValue);
							rootEle.appendChild(ele);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.CONTAINER.getValue()))
						{
							strValue = objDocumentContentMacro.getContinuityOfContent();
							//Adding UIDREF Type of Node
							ele = getSRContainerElement(dom,EnumValueType.CONTAINER.getValue(),strIdentifier,strRelationshipType,strCodeMeaning,strCodeValue,strCodingSchemeDesignator,strValue);
							rootEle.appendChild(ele);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.CODE.getValue()))
						{
							String strCVForCodeMacro = null;
							String strCSDForCodeMacro = null;
							String strCMForCodeMacro = null;
							String StrSNMD = null;
							CodeMacro objCodeMacro = objDocumentContentMacro.getCodeMacro();

							ConceptCodeSequence objConceptCodeSequence = objCodeMacro.getConceptCodeSequence();

							ISingleCollection<CodeSequenceMacroDependentItem> objCollection = (ISingleCollection<CodeSequenceMacroDependentItem>)objConceptCodeSequence.getValue();

							ICollectionIterator<CodeSequenceMacroDependentItem> objCollectionIterator = objCollection.iterator();
							while(objCollectionIterator.hasNext())
							{
								CodeSequenceMacroDependentItem objCodeSequenceMacroDependentItem2 = objCollectionIterator.next();
								CodeSequenceMacro objCodeSequenceMacro = objCodeSequenceMacroDependentItem2.getCodeSequenceMacro();
								
								strCVForCodeMacro = objCodeSequenceMacro.getCodeValue();
								strCMForCodeMacro = objCodeSequenceMacro.getCodeMeaning();
								strCSDForCodeMacro = objCodeSequenceMacro.getCodeSchemeDesignator();
								StrSNMD 			=objCodeSequenceMacro.getSNOMEDCTID();
								//Adding CODE Type of Node
								ele = getSRCodeElementSNMD(dom,EnumValueType.CODE.getValue(),strIdentifier,strRelationshipType,strCodeValue,strCodingSchemeDesignator,strCodeMeaning,strCVForCodeMacro,strCSDForCodeMacro,strCMForCodeMacro,StrSNMD);
								rootEle.appendChild(ele);
							}
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.COMPOSITE.getValue()))
						{
							CompositeObjectReferenceMacro objCompositeObjectReferenceMacro = objDocumentContentMacro.getCompositeObjectReferenceMacro();
							ReferencedSOPSequence objReferencedSOPSequence = objCompositeObjectReferenceMacro.getReferencedSOPSequence();
							ISingleCollection<ReferencedSOPSequenceItem> objSingleCollection = (ISingleCollection<ReferencedSOPSequenceItem>)objReferencedSOPSequence.getValue();

							for (ReferencedSOPSequenceItem item : objSingleCollection) 
							{
								String strRefSOPClassUID =  item.getSOPInstanceReferenceMacro().getReferencedSOPClassUID();
							
								String strRefInstanceUID = item.getSOPInstanceReferenceMacro().getReferencedSOPInstanceUID();
								
								//Adding COMPOSITE Type of Node
								ele = getSRCompositeElement(dom,EnumValueType.COMPOSITE.getValue(),strIdentifier,strRelationshipType,strCodeValue,strCodingSchemeDesignator,strCodeMeaning,strRefSOPClassUID,strRefInstanceUID);
								rootEle.appendChild(ele);
								
							}
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.WAVEFORM.getValue()))
						{
							WaveformReferenceMacro objWaveformReferenceMacro = objDocumentContentMacro.getWaveformReferenceMacro();
							CompositeObjectReferenceMacro objCompositeObjectReferenceMacro = objWaveformReferenceMacro.getCompositeObjectReferenceMacro();

							ReferencedSOPSequence objReferencedSOPSequence = objCompositeObjectReferenceMacro.getReferencedSOPSequence();
							ISingleCollection<ReferencedSOPSequenceItem> objSingleCollection = (ISingleCollection<ReferencedSOPSequenceItem>)objReferencedSOPSequence.getValue();

							String strRefSOPClassUID = null;
							String strRefInstanceUID = null;
							for (ReferencedSOPSequenceItem item : objSingleCollection) 
							{
								strRefSOPClassUID =item.getSOPInstanceReferenceMacro().getReferencedSOPClassUID();
								
								strRefInstanceUID = item.getSOPInstanceReferenceMacro().getReferencedSOPInstanceUID();
								
							}

							// Retrieving value for Referenced Waveform Channels
							short [] sharrWRMC = objWaveformReferenceMacro.getReferencedWaveformChannels();
							
							String strRefCh = shortArrayToString(sharrWRMC);
							
							//Adding WAVWFORM Type of Node
							ele = getSRWaveformElement(dom,EnumValueType.WAVEFORM.getValue(),strIdentifier,strRelationshipType,strCodeValue,strCodingSchemeDesignator,strCodeMeaning,strRefSOPClassUID,strRefInstanceUID,strRefCh);
							rootEle.appendChild(ele);
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.SCOORD.getValue()))
						{
							SpatialCoordinatesMacro objSpatialCoordinatesMacro = objDocumentContentMacro.getSpatialCoordinatesMacro();

							float []arrflGraphicData = objSpatialCoordinatesMacro.getGraphicData();

							String strGraphicData = floatArrayToString(arrflGraphicData);

							String strGraphicType = objSpatialCoordinatesMacro.getGraphicType();
							
							//Adding SCOORD Type of Node
							ele = getSRSCOORDElement(dom,EnumValueType.SCOORD.getValue(),strIdentifier,strRelationshipType,strCodeValue,strCodingSchemeDesignator,strCodeMeaning,strGraphicData,strGraphicType);
							rootEle.appendChild(ele);
						
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.NUM.getValue()))
						{
							NumericMeasurementMacro objNumericMeasurementMacro = objDocumentContentMacro.getNumericMeasurementMacro();
							MeasuredValueSequence objMeasuredValueSequence = objNumericMeasurementMacro.getMeasuredValueSequence();
							ISingleCollection<MeasuredValueSequenceItem> objSingleCollection = (ISingleCollection<MeasuredValueSequenceItem>)objMeasuredValueSequence.getValue();

							for (MeasuredValueSequenceItem item : objSingleCollection) 
							{
								String [] arrStrNV = item.getNumericValue();
								
								String strNumericValue = stringArrayToString(arrStrNV);

								//Retrieves MeasurementUnitsCodeSequence
								MeasurementUnitsCodeSequence objMeasurementUnitsCodeSequence = item.getMeasurementUnitsCodeSequence();
								ISingleCollection<CodeSequenceMacroDependentItem> objCollection = (ISingleCollection<CodeSequenceMacroDependentItem>)objMeasurementUnitsCodeSequence.getValue();

								String strCVForMUCS = null;
								String strCSDForMUCS = null;
								String strCSVForMUCS = null;
								String strCMForMUCS = null;
								for(CodeSequenceMacroDependentItem itemCSMDI : objCollection)
								{
									CodeSequenceMacro objCodeSequenceMacro = itemCSMDI.getCodeSequenceMacro();

									strCVForMUCS = objCodeSequenceMacro.getCodeValue();
									strCSDForMUCS = objCodeSequenceMacro.getCodeSchemeDesignator();
									strCSVForMUCS = objCodeSequenceMacro.getCodingSchemeVersion();
									strCMForMUCS = objCodeSequenceMacro.getCodeMeaning();
								}

								//Retrieves Numeric Value Qualifier Code Sequence
								NumericValueQualifierCodeSequence objNumericValueQualifierCodeSequence = objNumericMeasurementMacro.getNumericValueQualifierCodeSequence();
								ISingleCollection<CodeSequenceMacroDependentItem> objCollection2 = (ISingleCollection<CodeSequenceMacroDependentItem>)objNumericValueQualifierCodeSequence.getValue();

								String strCVForNVQCS = null;
								String strCSDForNVQCS = null;
								String strCSVForNVQCS = null;
								String strCMForNVQCS = null;
								for(CodeSequenceMacroDependentItem itemCSMDI : objCollection2)
								{
									CodeSequenceMacro objCodeSequenceMacro = itemCSMDI.getCodeSequenceMacro();

									strCVForNVQCS = objCodeSequenceMacro.getCodeValue();
									strCSDForNVQCS = objCodeSequenceMacro.getCodeSchemeDesignator();
									strCSVForNVQCS = objCodeSequenceMacro.getCodingSchemeVersion();
									strCMForNVQCS = objCodeSequenceMacro.getCodeMeaning();
								}
								
								//Adding NUM Type of Node
								ele = getSRNumElement(dom,EnumValueType.NUM.getValue(),strIdentifier,strRelationshipType,strCodeValue,
																strCodingSchemeDesignator,strCodeMeaning,strNumericValue,strCVForMUCS,strCSDForMUCS,
																strCSVForMUCS,strCMForMUCS,strCVForNVQCS,strCSDForNVQCS,strCSVForNVQCS,strCMForNVQCS);
								rootEle.appendChild(ele);
							}
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.IMAGE.getValue()))
						{
							ImageReferenceMacro objImageReferenceMacro = objDocumentContentMacro.getImageReferenceMacro();

							//ReferencedSOPSequence in CompositeObjectReferenceMacro
							CompositeObjectReferenceMacro objCompositeObjectReferenceMacro = objImageReferenceMacro.getCompositeObjectReferenceMacro();
							ReferencedSOPSequence objReferencedSOPSequence = objCompositeObjectReferenceMacro.getReferencedSOPSequence();
							ISingleCollection<ReferencedSOPSequenceItem> objSingleCollection = (ISingleCollection<ReferencedSOPSequenceItem>)objReferencedSOPSequence.getValue();

							String strRefSOPClassUIDForCRM = null;
							String strRefSOPInstanceUIDForCRM = null;
							for (ReferencedSOPSequenceItem item : objSingleCollection) 
							{
								strRefSOPClassUIDForCRM = item.getSOPInstanceReferenceMacro().getReferencedSOPClassUID();
								
								strRefSOPInstanceUIDForCRM = item.getSOPInstanceReferenceMacro().getReferencedSOPInstanceUID();
							}

							// Referenced Fame Number
							String [] strarrRefFramNo = objImageReferenceMacro.getReferencedFrameNumber();
							String strRefFrmNumb = stringArrayToString(strarrRefFramNo);

							//ReferencedSOPSequence in Image Referenced Macro
							ReferencedSOPSequence objReferencedSOPSequence1 = objImageReferenceMacro.getReferencedSOPSequence();
							ISingleCollection<ReferencedSOPSequenceItem> objSingleCollection1 = (ISingleCollection<ReferencedSOPSequenceItem>)objReferencedSOPSequence1.getValue();

							String strRefSOPClassUIDForRSS = null;
							String strRefSOPInstanceUIDForRSS = null;
							for (ReferencedSOPSequenceItem item : objSingleCollection1) 
							{
								strRefSOPClassUIDForRSS = item.getSOPInstanceReferenceMacro().getReferencedSOPClassUID();
								
								strRefSOPInstanceUIDForRSS = item.getSOPInstanceReferenceMacro().getReferencedSOPInstanceUID();
							}
							//Adding TCOORD Type of Node
							ele = getSRImageElement(dom,EnumValueType.IMAGE.getValue(),strIdentifier,strRelationshipType,strCodeValue,
									strCodingSchemeDesignator,strCodeMeaning,strRefSOPClassUIDForCRM,
									strRefSOPInstanceUIDForCRM,strRefFrmNumb,strRefSOPClassUIDForRSS,strRefSOPInstanceUIDForRSS);
							rootEle.appendChild(ele);
							
						}
						else if(objDocumentContentMacro.getValueType().equalsIgnoreCase(EnumValueType.TCOORD.getValue()))
						{
							TemporalCoordinatesMacro objTemporalCoordinatesMacro = objDocumentContentMacro.getTemporalCoordinatesMacro();

							//Get Referenced Date Time 
							String []arr = objTemporalCoordinatesMacro.getReferencedDatetime();
							String strRefDateTime = stringArrayToString(arr);
							
							//Get Referenced Sample Position.
							int[] larr = objTemporalCoordinatesMacro.getReferencedSamplePositions();
							String strRefSamplePosition = intArrayToString(larr);

							//Get Referenced Date Time 
							arr = objTemporalCoordinatesMacro.getReferencedTimeOffsets();
							String strRefTimeOffsets = stringArrayToString(arr);

							//Get Temporal Range Type
							String strTemporalRangeType =  objTemporalCoordinatesMacro.getTemporalRangeType();

							//Adding TCOORD Type of Node
							ele = getSRTCOORDElement(dom,EnumValueType.TCOORD.getValue(),strIdentifier,strRelationshipType,strCodeValue,strCodingSchemeDesignator,strCodeMeaning,strTemporalRangeType,strRefSamplePosition,strRefTimeOffsets,strRefDateTime);
							rootEle.appendChild(ele);
							
						}

						/**
						 * This part of code retrieves the Document Relationship macro, if the Content Sequence present in 
						 * Doc Relationship Macro for this ContentSequenceItem has another ContentSequence Item in it, 
						 * then it will again call Display method to serialize that Item too.
						 * For eg. If CODE type of node itself contains another say, PNAME type of node, then it will serialize
						 * that PNAME type of node.
						 */
						DocumentRelationshipMacro objDocumentRelationshipMacroToGetInnerContentSQ = objContentSequenceItemForInner.getDocumentRelationshipMacro();
						if(objDocumentRelationshipMacroToGetInnerContentSQ != null)
							serializeXMLNode(dom, ele, objCodeSequenceMacroDependentItemForInner, objDocumentRelationshipMacroToGetInnerContentSQ);
					}
				}
			}
		}
	}
	
	/**
	 * Returns the element Filled with  the information like ContemtLable(Referenced Content Item Identifier),RelationshipType,
	 * CodeValue,CodingSchemeDesignator, CodeMeaning of that node.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type. 
	 * @param strContentLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @return eleValueType Object Element.
	 */
	private Element fillInfo(Document dom,String strValueType,String strContentLable,String strRelationshipType, 
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning)
	{
		//creates the element with value type strValueType.
		Element eleValueType = dom.createElement(strValueType);

		// Content Label
		Element eleContentLabel = dom.createElement("ContentLable");
		Text txtContemtLabel = dom.createTextNode(strContentLable);
		eleContentLabel.appendChild(txtContemtLabel);
		eleValueType.appendChild(eleContentLabel);

		// Relationship Type
		Element eleRelationshipType = dom.createElement("RelationshipType");
		Text txtRelationshipType = dom.createTextNode(strRelationshipType);
		eleRelationshipType.appendChild(txtRelationshipType);
		eleValueType.appendChild(eleRelationshipType);

		// Concept Name Code Sequence
		Element eleConceptNameCodeSequence = dom.createElement("ConceptNameCodeSequence");
		
		// Code Value
		Element eleCodeValue = dom.createElement("CodeValue");
		Text txtCodeValue = dom.createTextNode(strCodeValue);
		eleCodeValue.appendChild(txtCodeValue);
		eleConceptNameCodeSequence.appendChild(eleCodeValue);

		// Coding Scheme Designator
		Element eleCodingSchemeDesignator = dom.createElement("CodingSchemeDesignator");
		Text txtCodingSchemeDesignator = dom.createTextNode(strCodingSchemeDesignator);
		eleCodingSchemeDesignator.appendChild(txtCodingSchemeDesignator);
		eleConceptNameCodeSequence.appendChild(eleCodingSchemeDesignator);

		// Code Meaning
		Element eleCodeMeaning = dom.createElement("CodeMeaning");
		Text txtCodeMeaning = dom.createTextNode(strCodeMeaning);
		eleCodeMeaning.appendChild(txtCodeMeaning);
		eleConceptNameCodeSequence.appendChild(eleCodeMeaning);

		eleValueType.appendChild(eleConceptNameCodeSequence);	
		
		return eleValueType;
	}

	/**
	 * Gives the Element for specified value type which can be added in the Root node.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type. It can be one of the value -
	 * 		  PNAME,TEXT,DATETIME,DATE,TIME,UIDREF
	 * @param strContemtLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @param strValue value for node.
	 * @return eleValueType Object Element.
	 */
	private Element getSRElement(Document dom,String strValueType,String strContemtLable,String strRelationshipType, 
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, String strValue)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fillInfo(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning);

		if(strValueType.equalsIgnoreCase("PNAME"))
		{
			Element eleValue = dom.createElement("PersonName");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("TEXT"))
		{
			Element eleValue = dom.createElement("TextValue");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("DATETIME"))
		{
			Element eleValue = dom.createElement("DateTime");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("DATE"))
		{
			Element eleValue = dom.createElement("Date");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("TIME"))
		{
			Element eleValue = dom.createElement("Time");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("UIDREF"))
		{
			Element eleValue = dom.createElement("UIDREF");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		return eleValueType;
	}
	
	/**
	 * Gives the Element for CONTAINER value type which can be added in the Root node.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type CONTAINER. 
	 * @param strContemtLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @param strContinuityOfContent String value for Continuity Of Content.
	 * @return eleValueType Object Element of type CONTAINER.
	 */
	private Element getSRContainerElement(Document dom,String strValueType,String strContemtLable,String strRelationshipType, 
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, String strContinuityOfContent)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fillInfo(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning);

		if(strValueType.equalsIgnoreCase(EnumValueType.CONTAINER.getValue()))
		{
			Element eleValue = dom.createElement("ContinuityOfContent");
			Text txtValue = dom.createTextNode(strContinuityOfContent);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		return eleValueType;
	}
	
	/**
	 * Gives the Element for specified value type which can be added in the Root node.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type CODE. 
	 * @param strContemtLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @param strCVForCodeMacro  String value for Code Value in Code Macro.
	 * @param strCSDForCodeMacro String value for Coding Scheme Designator in Code Macro.
	 * @param strCMForCodeMacro String value for Code Meaning in Code Macro.
	 * @return eleValueType Object Element of type CODE.
	 */
	private Element getSRCodeElement(Document dom,String strValueType,String strContemtLable,String strRelationshipType,
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, 
			String strCVForCodeMacro, String strCSDForCodeMacro,String strCMForCodeMacro)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fillInfo(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning);

		if(strValueType.equalsIgnoreCase(EnumValueType.CODE.getValue()))
		{
			Element eleValue = dom.createElement("CodeMacro");
			
			//Element eleConcptCodeSequence = dom.createElement("ConceptCodeSequence");
			
			//Code Value
			Element eleCodeValue = dom.createElement("CodeValue");
			Text txtCodeValue = dom.createTextNode(strCVForCodeMacro);
			eleCodeValue.appendChild(txtCodeValue);
			eleValue.appendChild(eleCodeValue);
			//eleConcptCodeSequence.appendChild(eleCodeValue);

			// Coding Scheme Designator
			Element eleCodingSchemeDesignator = dom.createElement("CodingSchemeDesignator");
			Text txtCodingSchemeDesignator = dom.createTextNode(strCSDForCodeMacro);
			eleCodingSchemeDesignator.appendChild(txtCodingSchemeDesignator);
			eleValue.appendChild(eleCodingSchemeDesignator);
			//eleConcptCodeSequence.appendChild(eleCodingSchemeDesignator);

			// Code Meaning
			Element eleCodeMeaning = dom.createElement("CodeMeaning");
			Text txtCodeMeaning = dom.createTextNode(strCMForCodeMacro);
			eleCodeMeaning.appendChild(txtCodeMeaning);
			eleValue.appendChild(eleCodeMeaning);
			//eleConcptCodeSequence.appendChild(eleCodeMeaning);

			//eleValue.appendChild(eleConcptCodeSequence);
			
			eleValueType.appendChild(eleValue);
		}
		
		return eleValueType;
	}
	
	/**
	 * Returns the Element for value type COMPOSITE filled with information required.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type CODE. 
	 * @param strContemtLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @param strRefSOPClassUID String value for ReferencedSOPClassUID.
	 * @param strRefSOPInstanceUID String value for ReferencedSOPInstanceUID.
	 * @return Object Element of type COMPOSITE.
	 */
	private Element getSRCompositeElement(Document dom,String strValueType,String strContemtLable,String strRelationshipType,
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, 
			String strRefSOPClassUID, String strRefSOPInstanceUID)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fillInfo(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning);

		if(strValueType.equalsIgnoreCase(EnumValueType.COMPOSITE.getValue()))
		{
			Element eleValue = dom.createElement("CompositeObjectReferenceMacro");
			
			//Referenced SOP Class UID
			Element eleReferencedSOPClassUID = dom.createElement("ReferencedSOPClassUID");
			Text txtReferencedSOPClassUID = dom.createTextNode(strRefSOPClassUID);
			eleReferencedSOPClassUID.appendChild(txtReferencedSOPClassUID);
			eleValue.appendChild(eleReferencedSOPClassUID);

			//Referenced SOP Instance UID
			Element eleReferencedSOPInstanceUID = dom.createElement("ReferencedSOPInstanceUID");
			Text txtReferencedSOPInstanceUID = dom.createTextNode(strRefSOPInstanceUID);
			eleReferencedSOPInstanceUID.appendChild(txtReferencedSOPInstanceUID);
			eleValue.appendChild(eleReferencedSOPInstanceUID);

			eleValueType.appendChild(eleValue);
		}
		
		return eleValueType;
	}
	
	/**
	 * Returns the Element for value type WAVEFORM filled with information required.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type CODE. 
	 * @param strContemtLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @param strRefSOPClassUID String value for ReferencedSOPClassUID.
	 * @param strRefSOPInstanceUID String value for ReferencedSOPInstanceUID.
	 * @param strRefWavCh  String value for Referenced Waveform Channels.
	 * @return Object Element of type WAVEFORM.
	 */
	private Element getSRWaveformElement(Document dom,String strValueType,String strContemtLable,String strRelationshipType,
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, 
			String strRefSOPClassUID, String strRefSOPInstanceUID, String strRefWavCh)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fillInfo(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning);

		if(strValueType.equalsIgnoreCase(EnumValueType.WAVEFORM.getValue()))
		{
			//Waveform Reference Macro
			Element eleValue = dom.createElement("WaveformReferenceMacro");
			
			Element eleComRefMacro = dom.createElement("CompositeObjectReferenceMacro");
			
			//Referenced SOP Class UID
			Element eleReferencedSOPClassUID = dom.createElement("ReferencedSOPClassUID");
			Text txtReferencedSOPClassUID = dom.createTextNode(strRefSOPClassUID);
			eleReferencedSOPClassUID.appendChild(txtReferencedSOPClassUID);
			eleComRefMacro.appendChild(eleReferencedSOPClassUID);

			//Referenced SOP Instance UID
			Element eleReferencedSOPInstanceUID = dom.createElement("ReferencedSOPInstanceUID");
			Text txtReferencedSOPInstanceUID = dom.createTextNode(strRefSOPInstanceUID);
			eleReferencedSOPInstanceUID.appendChild(txtReferencedSOPInstanceUID);
			eleComRefMacro.appendChild(eleReferencedSOPInstanceUID);
			
			eleValue.appendChild(eleComRefMacro);
			
			//Referenced Waveform Channels
			Element eleReferencedWaveformChannels = dom.createElement("ReferencedWaveformChannels");
			Text txtRefWavCh = dom.createTextNode(strRefWavCh);
			eleReferencedWaveformChannels.appendChild(txtRefWavCh);
			
			eleValue.appendChild(eleReferencedWaveformChannels);

			eleValueType.appendChild(eleValue);
		}
		
		return eleValueType;
	}
	
	/**
	 * Returns the Element for value type SCOORD filled with information required.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type CODE. 
	 * @param strContemtLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @param strGraphicData String value for Graphic Data
	 * @param strGraphicType String value for Graphic Type
	 * @return Object Element of type SCOORD
	 */
	private Element getSRSCOORDElement(Document dom,String strValueType,String strContemtLable,String strRelationshipType,
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, 
			String strGraphicData, String strGraphicType)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fillInfo(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning);

		if(strValueType.equalsIgnoreCase(EnumValueType.SCOORD.getValue()))
		{
			Element eleValue = dom.createElement("SpatialCoordinatesMacro");
			
			//Graphic Data
			Element eleGraphicData = dom.createElement("GraphicData");
			Text txtGraphicData = dom.createTextNode(strGraphicData);
			eleGraphicData.appendChild(txtGraphicData);
			eleValue.appendChild(eleGraphicData);

			//Graphic Type
			Element eleGraphicType = dom.createElement("GraphicType");
			Text txtGraphicType = dom.createTextNode(strGraphicType);
			eleGraphicType.appendChild(txtGraphicType);
			eleValue.appendChild(eleGraphicType);

			eleValueType.appendChild(eleValue);
		}
		
		return eleValueType;
	}
	
	/**
	 * Returns the Element for value type TCOORD filled with information required.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type CODE. 
	 * @param strContemtLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @param strTemporalRangeType String value for TemporalRangeType
	 * @param strReferencedSamplePositions String value for ReferencedSamplePositions
	 * @param strReferencedTimeOffsets String value for ReferencedTimeOffsets
	 * @param strReferencedDatetime String value for ReferencedDatetime
	 * @return Object Element of type TCOORD
	 */
	private Element getSRTCOORDElement(Document dom,String strValueType,String strContemtLable,String strRelationshipType,
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, 
			String strTemporalRangeType, String strReferencedSamplePositions, String strReferencedTimeOffsets, String strReferencedDatetime)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fillInfo(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning);

		if(strValueType.equalsIgnoreCase(EnumValueType.TCOORD.getValue()))
		{
			Element eleValue = dom.createElement("TemporalCoordinatesMacro");
			
			//Temporal Range Type
			Element eleTemporalRangeType = dom.createElement("TemporalRangeType");
			Text txtTemporalRangeType = dom.createTextNode(strTemporalRangeType);
			eleTemporalRangeType.appendChild(txtTemporalRangeType);
			eleValue.appendChild(eleTemporalRangeType);

			//Referenced Sample Positions
			Element eleReferencedSamplePositions = dom.createElement("ReferencedSamplePositions");
			Text txtReferencedSamplePositions = dom.createTextNode(strReferencedSamplePositions);
			eleReferencedSamplePositions.appendChild(txtReferencedSamplePositions);
			eleValue.appendChild(eleReferencedSamplePositions);
			
			//Referenced Time Offsets
			Element eleReferencedTimeOffsets = dom.createElement("ReferencedTimeOffsets");
			Text txtReferencedTimeOffsets = dom.createTextNode(strReferencedTimeOffsets);
			eleReferencedTimeOffsets.appendChild(txtReferencedTimeOffsets);
			eleValue.appendChild(eleReferencedTimeOffsets);

			//Referenced Datetime
			Element eleReferencedDatetime = dom.createElement("ReferencedDatetime");
			Text txtReferencedDatetime = dom.createTextNode(strReferencedDatetime);
			eleReferencedDatetime.appendChild(txtReferencedDatetime);
			eleValue.appendChild(eleReferencedDatetime);

			eleValueType.appendChild(eleValue);
		}
		
		return eleValueType;
	}
	
	/**
	 * Returns the Element for value type NUM filled with information required.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type CODE. 
	 * @param strContemtLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @param strNumericValue String value for Numeric value.
	 * @param strCVForUnitSQ String value for code value of Measurement Units Code Sequence.
	 * @param strCSDForUnitSQ String value for coding scheme designator of Measurement Units Code Sequence.
	 * @param strCSVForUnitSQ String value for coding scheme version of Measurement Units Code Sequence.
	 * @param strCMForUnitSQ String value for code meaning of Measurement Units Code Sequence.
	 * @param strCVForNumValQuaCodeSQ String value for code value of Numeric Value Qualifier Code Sequence.
	 * @param strCSDForNumValQuaCodeSQ String value for coding scheme designator of Numeric Value Qualifier Code Sequence.
	 * @param strCSVForNumValQuaCodeSQ String value for coding scheme version of Numeric Value Qualifier Code Sequence.
	 * @param strCMForNumValQuaCodeSQ String value for code meaning of Numeric Value Qualifier Code Sequence.
	 * @return Object Element of type NUM.
	 */
	private Element getSRNumElement(Document dom,String strValueType,String strContemtLable,String strRelationshipType,
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, String strNumericValue ,
			String strCVForUnitSQ, String strCSDForUnitSQ,String strCSVForUnitSQ,String strCMForUnitSQ,
			String strCVForNumValQuaCodeSQ ,String strCSDForNumValQuaCodeSQ,String strCSVForNumValQuaCodeSQ,String strCMForNumValQuaCodeSQ)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fillInfo(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning);

		if(strValueType.equalsIgnoreCase(EnumValueType.NUM.getValue()))
		{
			Element eleNumericMeasurementMacro = dom.createElement("NumericMeasurementMacro");
			
			Element eleMeasuredValueSequence = dom.createElement("MeasuredValueSequence");
			
			//Numeric Value
			Element eleNumericValue = dom.createElement("NumericValue");
			Text txtNumericValue = dom.createTextNode(strNumericValue);
			eleNumericValue.appendChild(txtNumericValue);
			
			eleMeasuredValueSequence.appendChild(eleNumericValue);
			
				//Measurement Units Code Sequence
				Element eleMUCS = dom.createElement("MeasurementUnitsCodeSequence");
				
				//Code Value
				Element eleCodeValue = dom.createElement("CodeValue");
				Text txtCodeValue = dom.createTextNode(strCVForUnitSQ);
				eleCodeValue.appendChild(txtCodeValue);
				eleMUCS.appendChild(eleCodeValue);
	
				// Coding Scheme Designator
				Element eleCodingSchemeDesignator = dom.createElement("CodingSchemeDesignator");
				Text txtCodingSchemeDesignator = dom.createTextNode(strCSDForUnitSQ);
				eleCodingSchemeDesignator.appendChild(txtCodingSchemeDesignator);
				eleMUCS.appendChild(eleCodingSchemeDesignator);
				
				//Coding Scheme Version
				Element eleCSV = dom.createElement("CodingSchemeVersion");
				Text txtCodingSchemeVersion = dom.createTextNode(strCSVForUnitSQ);
				eleCSV.appendChild(txtCodingSchemeVersion);
				eleMUCS.appendChild(eleCSV);
	
				// Code Meaning
				Element eleCodeMeaning = dom.createElement("CodeMeaning");
				Text txtCodeMeaning = dom.createTextNode(strCMForUnitSQ);
				eleCodeMeaning.appendChild(txtCodeMeaning);
				eleMUCS.appendChild(eleCodeMeaning);
			
			eleMeasuredValueSequence.appendChild(eleMUCS);
			eleNumericMeasurementMacro.appendChild(eleMeasuredValueSequence);
			
				//Numeric Value Qualifier Code Sequence
				Element eleNVQCS = dom.createElement("NumericValueQualifierCodeSequence");
				
				//Code Value
				eleCodeValue = dom.createElement("CodeValue");
				txtCodeValue = dom.createTextNode(strCVForNumValQuaCodeSQ);
				eleCodeValue.appendChild(txtCodeValue);
				eleNVQCS.appendChild(eleCodeValue);
	
				// Coding Scheme Designator
				eleCodingSchemeDesignator = dom.createElement("CodingSchemeDesignator");
				txtCodingSchemeDesignator = dom.createTextNode(strCSDForNumValQuaCodeSQ);
				eleCodingSchemeDesignator.appendChild(txtCodingSchemeDesignator);
				eleNVQCS.appendChild(eleCodingSchemeDesignator);
				
				//Coding Scheme Version
				eleCSV = dom.createElement("CodingSchemeVersion");
				txtCodingSchemeVersion = dom.createTextNode(strCSVForNumValQuaCodeSQ);
				eleCSV.appendChild(txtCodingSchemeVersion);
				eleNVQCS.appendChild(eleCSV);
	
				// Code Meaning
				eleCodeMeaning = dom.createElement("CodeMeaning");
				txtCodeMeaning = dom.createTextNode(strCMForNumValQuaCodeSQ);
				eleCodeMeaning.appendChild(txtCodeMeaning);
				eleNVQCS.appendChild(eleCodeMeaning);
			
				eleNumericMeasurementMacro.appendChild(eleNVQCS);

			eleValueType.appendChild(eleNumericMeasurementMacro);
		}
		
		return eleValueType;
	}
	
	/**
	 * Returns the Element for value type IMAGE filled with information required.
	 * @param dom Object of Document.
	 * @param strValueType String value for Value Type CODE. 
	 * @param strContemtLable String value for Referenced Content Item Identifier.
	 * @param strRelationshipType String value for Relationship Type.
	 * @param strCodeValue String value for Code Value.
	 * @param strCodingSchemeDesignator String value for Coding Scheme Designator.
	 * @param strCodeMeaning String value for Code Meaning.
	 * @param strRefSOPClassUIDForCORefMacro String value for RefSOPClassUID For CORefMacro.
	 * @param strRefSOPInstanceUIDForCORefMacro String value for RefSOPInstanceUID For CORefMacro.
	 * @param strReferencedFrameNumber String value for ReferencedFrameNumber.
	 * @param strRefSOPClassUID String value for RefSOPClassUID for Referenced SOP Sequence.
	 * @param strRefSOPInstanceUID String value for RefSOPInstanceUID for Referenced SOP Sequence.
	 * @return Object Element of type IMAGE
	 */
	private Element getSRImageElement(Document dom,String strValueType,String strContemtLable,String strRelationshipType,
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning,String strRefSOPClassUIDForCORefMacro,
			String strRefSOPInstanceUIDForCORefMacro,String strReferencedFrameNumber,
			String strRefSOPClassUID, String strRefSOPInstanceUID)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fillInfo(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning);

		if(strValueType.equalsIgnoreCase(EnumValueType.IMAGE.getValue()))
		{
			Element eleImageReferenceMacro = dom.createElement("ImageReferenceMacro");
			
			Element eleComRefMacro = dom.createElement("CompositeObjectReferenceMacro");
			
			//Referenced SOP Class UID
			Element eleReferencedSOPClassUID = dom.createElement("ReferencedSOPClassUID");
			Text txtReferencedSOPClassUID = dom.createTextNode(strRefSOPClassUIDForCORefMacro);
			eleReferencedSOPClassUID.appendChild(txtReferencedSOPClassUID);
			eleComRefMacro.appendChild(eleReferencedSOPClassUID);

			//Referenced SOP Instance UID
			Element eleReferencedSOPInstanceUID = dom.createElement("ReferencedSOPInstanceUID");
			Text txtReferencedSOPInstanceUID = dom.createTextNode(strRefSOPInstanceUIDForCORefMacro);
			eleReferencedSOPInstanceUID.appendChild(txtReferencedSOPInstanceUID);
			eleComRefMacro.appendChild(eleReferencedSOPInstanceUID);
			
			eleImageReferenceMacro.appendChild(eleComRefMacro);
			
			//Referenced Frame Number
			Element eleReferencedFrameNumber = dom.createElement("ReferencedFrameNumber");
			Text txtReferencedFrameNumber = dom.createTextNode(strReferencedFrameNumber);
			eleReferencedFrameNumber.appendChild(txtReferencedFrameNumber);
			eleImageReferenceMacro.appendChild(eleReferencedFrameNumber);
			
			// Referenced SOP Sequence
			Element eleRefSOPSQ = dom.createElement("ReferencedSOPSequence");
			
			//Referenced SOP Class UID
			eleReferencedSOPClassUID = dom.createElement("ReferencedSOPClassUID");
			txtReferencedSOPClassUID = dom.createTextNode(strRefSOPClassUID);
			eleReferencedSOPClassUID.appendChild(txtReferencedSOPClassUID);
			eleRefSOPSQ.appendChild(eleReferencedSOPClassUID);

			//Referenced SOP Instance UID
			eleReferencedSOPInstanceUID = dom.createElement("ReferencedSOPInstanceUID");
			txtReferencedSOPInstanceUID = dom.createTextNode(strRefSOPInstanceUID);
			eleReferencedSOPInstanceUID.appendChild(txtReferencedSOPInstanceUID);
			eleRefSOPSQ.appendChild(eleReferencedSOPInstanceUID);
			
			eleImageReferenceMacro.appendChild(eleRefSOPSQ);

			eleValueType.appendChild(eleImageReferenceMacro);
		}
		
		return eleValueType;
	}
	
	/**
	 * Converters integer array to String value.
	 * @param arr Array of Integer.
	 * @return strVal String value.
	 */
	private String intArrayToString(int []arr)
	{
		int ilenght = arr.length;
		String strVal = null;
		for(int i=0; i < ilenght; i++)
		{
			int iValue = arr[i];
			if(i==0)
				strVal = "" + iValue;
			else
				strVal = strVal + iValue;

			if(i < ilenght -1)
				strVal = strVal + "," ;
		}
		return strVal;
	}
	
	/**
	 * Converters short array to String value.
	 * @param arr Array of short.
	 * @return strVal String value.
	 */
	private String shortArrayToString(short []arr)
	{
		int ilenght = arr.length;
		String strVal = null;
		for(int i=0; i < ilenght; i++)
		{
			short shValue = arr[i];
			if(i==0)
				strVal = "" + shValue;
			else
				strVal = strVal + shValue;

			if(i < ilenght -1)
				strVal = strVal + "," ;
		}
		return strVal;
	}
	
	/**
	 * Converters float array to String value.
	 * @param arr Array of float.
	 * @return strVal String value.
	 */
	private String floatArrayToString(float []arr)
	{
		int ilenght = arr.length;
		String strVal = null;
		for(int i=0; i < ilenght; i++)
		{
			float fValue = arr[i];
			if(i==0)
				strVal = "" + fValue;
			else
				strVal = strVal + fValue;

			if(i < ilenght -1)
				strVal = strVal + "," ;
		}
		return strVal;
	}
	
	/**
	 * Converters string array to String value.
	 * @param arr Array of string.
	 * @return strVal String value.
	 */
	private String stringArrayToString(String []arr)
	{
		int ilenght = arr.length;
		String strVal = null;
		for(int i=0; i < ilenght; i++)
		{
			String strValue = arr[i];
			if(i==0)
				strVal = "" + strValue;
			else
				strVal = strVal + strValue;

			if(i < ilenght -1)
				strVal = strVal + "," ;
		}
		return strVal;
	}



	@SuppressWarnings("unused")
	private void addTabs(int []arr)throws IOException
	{
		int []arrIdentifier = arr;
		int ilen = arrIdentifier.length;
		for(int i = 0; i<ilen; i++)
		{
			String objStrToWrite = "\t";
			byte [] b_array = objStrToWrite.getBytes();
			DicomFileStream objDicomFileStream = new DicomFileStream();
			objDicomFileStream.writeChars(b_array);
		}
	}
	
	private Element getSRElementSNMD(Document dom,String strValueType,String strContemtLable,String strRelationshipType, 
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, String strValue ,String strSNMDID)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fill(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning,strSNMDID);

		if(strValueType.equalsIgnoreCase("PNAME"))
		{
			Element eleValue = dom.createElement("PersonName");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("TEXT"))
		{
			Element eleValue = dom.createElement("TextValue");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("DATETIME"))
		{
			Element eleValue = dom.createElement("DateTime");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("DATE"))
		{
			Element eleValue = dom.createElement("Date");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("TIME"))
		{
			Element eleValue = dom.createElement("Time");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		else if(strValueType.equalsIgnoreCase("UIDREF"))
		{
			Element eleValue = dom.createElement("UIDREF");
			Text txtValue = dom.createTextNode(strValue);
			eleValue.appendChild(txtValue);
			eleValueType.appendChild(eleValue);
		}
		return eleValueType;
	}
	private Element fill(Document dom,String strValueType,String strContentLable,String strRelationshipType, 
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning,String strSNMDID)
	{
		//creates the element with value type strValueType.
		Element eleValueType = dom.createElement(strValueType);

		// Content Label
		Element eleContentLabel = dom.createElement("ContentLable");
		Text txtContemtLabel = dom.createTextNode(strContentLable);
		eleContentLabel.appendChild(txtContemtLabel);
		eleValueType.appendChild(eleContentLabel);

		// Relationship Type
		Element eleRelationshipType = dom.createElement("RelationshipType");
		Text txtRelationshipType = dom.createTextNode(strRelationshipType);
		eleRelationshipType.appendChild(txtRelationshipType);
		eleValueType.appendChild(eleRelationshipType);

		// Concept Name Code Sequence
		Element eleConceptNameCodeSequence = dom.createElement("ConceptNameCodeSequence");
		
		// Code Value
		Element eleCodeValue = dom.createElement("CodeValue");
		Text txtCodeValue = dom.createTextNode(strCodeValue);
		eleCodeValue.appendChild(txtCodeValue);
		eleConceptNameCodeSequence.appendChild(eleCodeValue);

		// Coding Scheme Designator
		Element eleCodingSchemeDesignator = dom.createElement("CodingSchemeDesignator");
		Text txtCodingSchemeDesignator = dom.createTextNode(strCodingSchemeDesignator);
		eleCodingSchemeDesignator.appendChild(txtCodingSchemeDesignator);
		eleConceptNameCodeSequence.appendChild(eleCodingSchemeDesignator);

		// Code Meaning
		Element eleCodeMeaning = dom.createElement("CodeMeaning");
		Text txtCodeMeaning = dom.createTextNode(strCodeMeaning);
		eleCodeMeaning.appendChild(txtCodeMeaning);
		eleConceptNameCodeSequence.appendChild(eleCodeMeaning);

		//Snmd
		Element elesnmd = dom.createElement("SNOMEDCTID");
		Text txtSNMD = dom.createTextNode(strSNMDID);
		eleCodeMeaning.appendChild(txtSNMD);
		eleConceptNameCodeSequence.appendChild(elesnmd);
		
		
		eleValueType.appendChild(eleConceptNameCodeSequence);	
		
		return eleValueType;
	}
	
	private Element getSRCodeElementSNMD(Document dom,String strValueType,String strContemtLable,String strRelationshipType,
			String strCodeValue,String strCodingSchemeDesignator, String strCodeMeaning, 
			String strCVForCodeMacro, String strCSDForCodeMacro,String strCMForCodeMacro ,String strSNMD)
	{
		//creates the element with value type strValueType.
		Element eleValueType = fill(dom, strValueType, strContemtLable, strRelationshipType, strCodeValue, strCodingSchemeDesignator, strCodeMeaning,strSNMD);

		if(strValueType.equalsIgnoreCase(EnumValueType.CODE.getValue()))
		{
			Element eleValue = dom.createElement("CodeMacro");
			
			//Element eleConcptCodeSequence = dom.createElement("ConceptCodeSequence");
			
			//Code Value
			Element eleCodeValue = dom.createElement("CodeValue");
			Text txtCodeValue = dom.createTextNode(strCVForCodeMacro);
			eleCodeValue.appendChild(txtCodeValue);
			eleValue.appendChild(eleCodeValue);
			//eleConcptCodeSequence.appendChild(eleCodeValue);

			// Coding Scheme Designator
			Element eleCodingSchemeDesignator = dom.createElement("CodingSchemeDesignator");
			Text txtCodingSchemeDesignator = dom.createTextNode(strCSDForCodeMacro);
			eleCodingSchemeDesignator.appendChild(txtCodingSchemeDesignator);
			eleValue.appendChild(eleCodingSchemeDesignator);
			//eleConcptCodeSequence.appendChild(eleCodingSchemeDesignator);

			// Code Meaning
			Element eleCodeMeaning = dom.createElement("CodeMeaning");
			Text txtCodeMeaning = dom.createTextNode(strCMForCodeMacro);
			eleCodeMeaning.appendChild(txtCodeMeaning);
			eleValue.appendChild(eleCodeMeaning);
			//eleConcptCodeSequence.appendChild(eleCodeMeaning);
			
			//Snmd
			Element elesnmd = dom.createElement("SNOMEDCTID");
			Text txtSNMD = dom.createTextNode(strSNMD);
			eleCodeMeaning.appendChild(txtSNMD);
			eleValue.appendChild(elesnmd);
			

			//eleValue.appendChild(eleConcptCodeSequence);
			
			eleValueType.appendChild(eleValue);
		}
		
		return eleValueType;
	}
}
