/*
 * #%L
 * BSD implementations of Bio-Formats readers and writers
 * %%
 * Copyright (C) 2005 - 2021 Open Microscopy Environment:
 *   - Board of Regents of the University of Wisconsin-Madison
 *   - Glencoe Software, Inc.
 *   - University of Dundee
 * %%
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * #L%
 */

package loci.formats.dicom;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

import loci.common.Constants;

import static loci.formats.dicom.DicomVR.*;

/**
 * Describes a DICOM attribute (integer tag, associated description, and expected VR).
 *
 * The full dictionary cannot be represented in an enum as it would greatly exceed
 * Java's bytecode size limitations. This is a subset of the dictionary which
 * includes attributes most likely to be directly referenced.
 * For the full dictionary, see dicom-dictionary.txt.
 */
public enum DicomAttribute {
    FILE_META_INFO_GROUP_LENGTH(0x00020000),
    FILE_META_INFO_VERSION(0x00020001),
    MEDIA_SOP_CLASS_UID(0x00020002),
    MEDIA_SOP_INSTANCE_UID(0x00020003),
    TRANSFER_SYNTAX_UID(0x00020010),
    IMPLEMENTATION_UID(0x00020012),
    IMPLEMENTATION_VERSION(0x00020013),
    SOURCE_APPLICATION(0x00020016),
    SPECIFIC_CHARSET(0x00080005),
    IMAGE_TYPE(0x00080008),
    RECOGNITION_CODE(0x00080010),
    CREATION_DATE(0x00080012),
    CREATION_TIME(0x00080013),
    INSTANCE_CREATOR(0x00080014),
    SOP_CLASS_UID(0x00080016),
    SOP_INSTANCE_UID(0x00080018),
    RELATED_SOP_CLASS_UID(0x0008001a),
    ORIGINAL_SOP_CLASS_UID(0x0008001b),
    STUDY_DATE(0x00080020),
    SERIES_DATE(0x00080021),
    ACQUISITION_DATE(0x00080022),
    CONTENT_DATE(0x00080023),
    OVERLAY_DATE(0x00080024),
    CURVE_DATE(0x00080025),
    ACQUISITION_TIMESTAMP(0x0008002a),
    STUDY_TIME(0x00080030),
    SERIES_TIME(0x00080031),
    ACQUISITION_TIME(0x00080032),
    CONTENT_TIME(0x00080033),
    OVERLAY_TIME(0x00080034),
    CURVE_TIME(0x00080035),
    DATASET_SUBTYPE(0x00080041),
    ACCESSION_NUMBER(0x00080050),
    QUERY_LEVEL(0x00080052),
    RETRIEVE_TITLE(0x00080054),
    INSTANCE_AVAILABILITY(0x00080056),
    FAILED_SOP_UID_LIST(0x00080058),
    MODALITY(0x00080060),
    MODALITIES_IN_STUDY(0x00080061),
    CLASSES_IN_STUDY(0x00080062),
    CONVERSION_TYPE(0x00080064),
    PRESENTATION_INTENT_TYPE(0x00080068),
    MANUFACTURER(0x00080070),
    INSTITUTION_NAME(0x00080080),
    INSTITUTION_ADDRESS(0x00080081),
    INSTITUTION_CODE_SEQUENCE(0x00080082),
    REFERRING_PHYSICIAN_NAME(0x00080090),
    REFERRING_PHYSICIAN_ADDRESS(0x00080092),
    REFERRING_PHYSICIAN_TELEPHONE(0x00080094),
    REFERRING_PHYSICIAN_ID(0x00080096),
    CODE_VALUE(0x00080100),
    CODING_SCHEME_DESIGNATOR(0x00080102),
    CODING_SCHEME_VERSION(0x00080103),
    CODE_MEANING(0x00080104),
    MAPPING_RESOURCE(0x00080105),
    CONTEXT_GROUP_VERSION(0x00080106),
    CONTEXT_GROUP_LOCAL_VERSION(0x00080107),
    CONTEXT_GROUP_EXTENSION_FLAG(0x0008010b),
    CODING_SCHEME_UID(0x0008010c),
    CONTEXT_GROUP_EXTENSION_CREATOR(0x0008010d),
    CONTEXT_ID(0x0008010f),
    CODING_SCHEME_ID(0x00080110),
    CODING_SCHEME_REGISTRY(0x00080112),
    CODING_SCHEME_EXTERNAL_ID(0x00080114),
    CODING_SCHEME_NAME(0x00080115),
    RESPONSIBLE_ORGANIZATION(0x00080116),
    TIMEZONE_OFFSET_UTC(0x00080201),
    STATION_NAME(0x00081010),
    STUDY_DESCRIPTION(0x00081030),
    PROCEDURE_CODE_SEQUENCE(0x00081032),
    SERIES_DESCRIPTION(0x0008103e),
    INSTITUTIONAL_DEPARTMENT_NAME(0x00081040),
    PHYSICIANS(0x00081048),
    PHYSICIANS_ID(0x00081049),
    PHYSICIAN_NAME(0x00081050),
    PHYSICIAN_ID(0x00081052),
    PHYSICIAN_READING(0x00081060),
    PHYSICIAN_READING_ID(0x00081062),
    OPERATOR_NAME(0x00081070),
    OPERATOR_ID(0x00081072),
    ADMITTING_DIAGNOSES_DESCRIPTION(0x00081080),
    ADMITTING_DIAGNOSES_CODE_SEQUENCE(0x00081084),
    MANUFACTURER_MODEL_NAME(0x00081090),
    REFERENCED_RESULTS_SEQUENCE(0x00081100),
    REFERENCED_STUDY_SEQUENCE(0x00081110),
    REFERENCED_PERFORMED_PROCEDURE_STEP(0x00081111),
    REFERENCED_SERIES_SEQUENCE(0x00081115),
    REFERENCED_PATIENT_SEQUENCE(0x00081120),
    REFERENCED_VISIT_SEQUENCE(0x00081125),
    REFERENCED_OVERLAY_SEQUENCE(0x00081130),
    REFERENCED_WAVEFORM_SEQUENCE(0x0008113a),
    REFERENCED_IMAGE_SEQUENCE(0x00081140),
    REFERENCED_CURVE_SEQUENCE(0x00081145),
    REFERENCED_INSTANCE_SEQUENCE(0x0008114a),
    REFERENCED_SOP_CLASS_UID(0x00081150),
    REFERENCED_SOP_INSTANCE_UID(0x00081155),
    SOP_CLASSES_SUPPORTED(0x0008115a),
    REFERENCED_FRAME_NUMBER(0x00081160),
    TRANSACTION_UID(0x00081195),
    FAILURE_REASON(0x00081197),
    FAILED_SOP_SEQUENCE(0x00081198),
    REFERENCED_SOP_SEQUENCE(0x00081199),
    STUDIES_WITH_REFERENCED_INSTANCES(0x00081200),
    RELATED_SERIES_SEQUENCE(0x00081250),
    DERIVATION_DESCRIPTION(0x00082111),
    SOURCE_IMAGE_SEQUENCE(0x00082112),
    STAGE_NAME(0x00082120),
    STAGE_NUMBER(0x00082122),
    NUMBER_OF_STAGES(0x00082124),
    VIEW_NAME(0x00082127),
    VIEW_NUMBER(0x00082128),
    NUMBER_OF_EVENT_TIMERS(0x00082129),
    NUMBER_OF_VIEWS_STAGE(0x0008212a),
    EVENT_ELAPSED_TIME(0x00082130),
    EVENT_TIMER_NAME(0x00082132),
    START_TRIM(0x00082142),
    STOP_TRIM(0x00082143),
    RECOMMENDED_DISPLAY_FRAMERATE(0x00082144),
    ANATOMIC_REGION_SEQUENCE(0x00082218),
    ANATOMIC_REGION_MODIFIER_SEQUENCE(0x00082220),
    PRIMARY_ANATOMIC_STRUCTURE_SEQUENCE(0x00082228),
    ANATOMIC_STRUCTURE_SEQUENCE(0x00082229),
    PRIMARY_ANATOMIC_STRUCTURE_MODIFIER(0x00082230),
    TRANSDUCER_POSITION_SEQUENCE(0x00082240),
    TRANSDUCER_POSITION_MODIFIER_SEQUENCE(0x00082242),
    TRANSDUCER_ORIENTATION_SEQUENCE(0x00082244),
    TRANSDUCER_ORIENTATION_MODIFIER(0x00082246),
    ALTERNATE_REPRESENTATION_SEQUENCE(0x00083001),
    FRAME_TYPE(0x00089007),
    REFERENCED_IMAGE_EVIDENCE_SEQUENCE(0x00089092),
    REFERENCED_RAW_DATA_SEQUENCE(0x00089121),
    CREATOR_VERSION_UID(0x00089123),
    DERIVATION_IMAGE_SEQUENCE(0x00089124),
    SOURCE_IMAGE_EVIDENCE_SEQUENCE(0x00089154),
    PIXEL_PRESENTATION(0x00089205),
    VOLUMETRIC_PROPERTIES(0x00089206),
    VOLUME_BASED_CALCULATION_TECHNIQUE(0x00089207),
    COMPLEX_IMAGE_COMPONENT(0x00089208),
    ACQUISITION_CONTRAST(0x00089209),
    DERIVATION_CODE_SEQUENCE(0x00089215),
    REFERENCE_GRAYSCALE_PRESENTATION_STATE(0x00089237),
    PATIENT_NAME(0x00100010),
    PATIENT_ID(0x00100020),
    ISSUER_OF_PATIENT_ID(0x00100021),
    PATIENT_BIRTH_DATE(0x00100030),
    PATIENT_BIRTH_TIME(0x00100032),
    PATIENT_SEX(0x00100040),
    PATIENT_INSURANCE_PLAN_CODE(0x00100050),
    PATIENT_PRIMARY_LANGUAGE_CODE(0x00100101),
    PATIENT_PRIMARY_LANGUAGE_MODIFIER(0x00100102),
    OTHER_PATIENT_IDS(0x00101000),
    OTHER_PATIENT_NAMES(0x00101001),
    PATIENT_BIRTH_NAME(0x00101005),
    PATIENT_AGE(0x00101010),
    PATIENT_SIZE(0x00101020),
    PATIENT_WEIGHT(0x00101030),
    PATIENT_ADDRESS(0x00101040),
    PATIENT_MOTHER_BIRTH_NAME(0x00101060),
    MILITARY_RANK(0x00101080),
    BRANCH_OF_SERVICE(0x00101081),
    MEDICAL_RECORD_LOCATOR(0x00101090),
    MEDICAL_ALERTS(0x00102000),
    CONTRAST_ALLERGIES(0x00102110),
    COUNTRY_OF_RESIDENCE(0x00102150),
    REGION_OF_RESIDENCE(0x00102152),
    PATIENT_TELEPHONE_NUMBER(0x00102154),
    ETHNIC_GROUP(0x00102160),
    OCCUPATION(0x00102180),
    SMOKING_STATUS(0x001021a0),
    ADDITIONAL_PATIENT_HISTORY(0x001021b0),
    PREGNANCY_STATUS(0x001021c0),
    LAST_MENSTRUAL_DATE(0x001021d0),
    PATIENT_RELIGIOUS_PREFERENCE(0x001021f0),
    PATIENT_COMMENTS(0x00104000),
    CLINICAL_TRIAL_SPONSOR_NAME(0x00120010),
    CLINICAL_TRIAL_PROTOCOL_ID(0x00120020),
    CLINICAL_TRIAL_PROTOCOL_NAME(0x00120021),
    CLINICAL_TRIAL_SITE_ID(0x00120030),
    CLINICAL_TRIAL_SITE_NAME(0x00120031),
    CLINICAL_TRIAL_SUBJECT_ID(0x00120040),
    CLINICAL_TRIAL_SUBJECT_READING_ID(0x00120042),
    CLINICAL_TRIAL_TIME_POINT_ID(0x00120050),
    CLINICAL_TRIAL_TIME_POINT_DESCRIPTION(0x00120051),
    CLINICAL_TRIAL_COORDINATING_CENTER(0x00120060),
    CONTRAST_BOLUS_AGENT(0x00180010),
    CONTRAST_BOLUS_AGENT_SEQUENCE(0x00180012),
    CONTRAST_BOLUS_ADMIN_ROUTE_SEQUENCE(0x00180014),
    BODY_PART_EXAMINED(0x00180015),
    SCANNING_SEQUENCE(0x00180020),
    SEQUENCE_VARIANT(0x00180021),
    SCAN_OPTIONS(0x00180022),
    MR_ACQUISITION_TYPE(0x00180023),
    SEQUENCE_NAME(0x00180024),
    ANGIO_FLAG(0x00180025),
    INTERVENTION_DRUG_INFORMATION_SEQUENCE(0x00180026),
    INTERVENTION_DRUG_STOP_TIME(0x00180027),
    INTERVENTION_DRUG_DOSE(0x00180028),
    INTERVENTION_DRUG_SEQUENCE(0x00180029),
    ADDITIONAL_DRUG_SEQUENCE(0x0018002a),
    RADIOPHARMACEUTICAL(0x00180031),
    INTERVENTION_DRUG_NAME(0x00180034),
    INTERVENTION_DRUG_START_TIME(0x00180035),
    INTERVENTION_SEQUENCE(0x00180036),
    INTERVENTION_STATUS(0x00180038),
    INTERVENTION_DESCRIPTION(0x0018003a),
    CINE_RATE(0x00180040),
    SLICE_THICKNESS(0x00180050),
    KVP(0x00180060),
    COUNTS_ACCUMULATED(0x00180070),
    ACQUISITION_TERMINATION_CONDITION(0x00180071),
    EFFECTIVE_DURATION(0x00180072),
    ACQUISITION_START_CONDITION(0x00180073),
    ACQUISITION_START_CONDITION_DATA(0x00180074),
    ACQUISITION_TERMINATION_CONDITION_DATA(0x00180075),
    REPETITION_TIME(0x00180080),
    ECHO_TIME(0x00180081),
    INVERSION_TIME(0x00180082),
    NUMBER_OF_AVERAGES(0x00180083),
    IMAGING_FREQUENCY(0x00180084),
    IMAGED_NUCLEUS(0x00180085),
    ECHO_NUMBER(0x00180086),
    MAGNETIC_FIELD_STRENGTH(0x00180087),
    SLICE_SPACING(0x00180088),
    NUMBER_OF_PHASE_ENCODING_STEPS(0x00180089),
    DATA_COLLECTION_DIAMETER(0x00180090),
    ECHO_TRAIN_LENGTH(0x00180091),
    PERCENT_SAMPLING(0x00180093),
    PERCENT_PHASE_FOV(0x00180094),
    PIXEL_BANDWIDTH(0x00180095),
    DEVICE_SERIAL_NUMBER(0x00181000),
    PLATE_ID(0x00181004),
    SECONDARY_CAPTURE_DEVICE_ID(0x00181010),
    HARDCOPY_CREATION_DEVICE_ID(0x00181011),
    DATE_OF_SECONDARY_CAPTURE(0x00181012),
    TIME_OF_SECONDARY_CAPTURE(0x00181014),
    SECONDARY_CAPTURE_DEVICE_MANUFACTURER(0x00181016),
    HARDCOPY_DEVICE_MANUFACTURER(0x00181017),
    SECONDARY_CAPTURE_DEVICE_MODEL_NAME(0x00181018),
    SECONDARY_CAPTURE_DEVICE_SOFTWARE_VERSION(0x00181019),
    HARDCOPY_DEVICE_SOFTWARE_VERSION(0x0018101a),
    HARDCOPY_DEVICE_MODEL_NAME(0x0018101b),
    SOFTWARE_VERSION(0x00181020),
    VIDEO_IMAGE_FORMAT_ACQUIRED(0x00181022),
    DIGITAL_IMAGE_FORMAT_ACQUIRED(0x00181023),
    PROTOCOL_NAME(0x00181030),
    CONTRAST_BOLUS_ROUTE(0x00181040),
    CONTRAST_BOLUS_VOLUME(0x00181041),
    CONTRAST_BOLUS_START_TIME(0x00181042),
    CONTRAST_BOLUS_STOP_TIME(0x00181043),
    CONTRAST_BOLUS_TOTAL_DOSE(0x00181044),
    SYRINGE_COUNTS(0x00181045),
    CONTRAST_FLOW_RATE(0x00181046),
    CONTRAST_FLOW_DURATION(0x00181047),
    CONTRAST_BOLUS_INGREDIENT(0x00181048),
    CONTRAST_INGREDIENT_CONCENTRATION(0x00181049),
    SPATIAL_RESOLUTION(0x00181050),
    TRIGGER_TIME(0x00181060),
    TRIGGER_SOURCE_OR_TYPE(0x00181061),
    NOMINAL_INTERVAL(0x00181062),
    FRAME_TIME(0x00181063),
    FRAMING_TYPE(0x00181064),
    FRAME_TIME_VECTOR(0x00181065),
    FRAME_DELAY(0x00181066),
    IMAGE_TRIGGER_DELAY(0x00181067),
    MULTIPLEX_GROUP_TIME_OFFSET(0x00181068),
    TRIGGER_TIME_OFFSET(0x00181069),
    SYNCHRONIZATION_TRIGGER(0x0018106a),
    SYNCHRONIZATION_CHANNEL(0x0018106c),
    TRIGGER_SAMPLE_POSITION(0x0018106e),
    RADIOPHARMACEUTICAL_ROUTE(0x00181070),
    RADIOPHARMACEUTICAL_VOLUME(0x00181071),
    RADIOPHARMACEUTICAL_START_TIME(0x00181072),
    RADIOPHARMACEUTICAL_STOP_TIME(0x00181073),
    RADIONUCLIDE_TOTAL_DOSE(0x00181074),
    RADIONUCLIDE_HALF_LIFE(0x00181075),
    RADIONUCLIDE_POSITRON_FRACTION(0x00181076),
    RADIOPHARMACEUTICAL_SPECIFIC_ACTIVITY(0x00181077),
    BEAT_REJECTION_FLAG(0x00181080),
    LOW_RR_VALUE(0x00181081),
    HIGH_RR_VALUE(0x00181082),
    INTERVALS_ACQUIRED(0x00181083),
    INTERVALS_REJECTED(0x00181084),
    PVC_REJECTION(0x00181085),
    SKIP_BEATS(0x00181086),
    HEART_RATE(0x00181088),
    CARDIAC_NUMBER_OF_IMAGES(0x00181090),
    TRIGGER_WINDOW(0x00181094),
    RECONSTRUCTION_DIAMETER(0x00181100),
    DISTANCE_SOURCE_TO_DETECTOR(0x00181110),
    DISTANCE_SOURCE_TO_PATIENT(0x00181111),
    ESTIMATED_RADIOGRAPHIC_MAG_FACTOR(0x00181114),
    GANTRY_DETECTOR_TILT(0x00181120),
    GANTRY_DETECTOR_SKEW(0x00181121),
    TABLE_HEIGHT(0x00181130),
    TABLE_TRAVERSE(0x00181131),
    TABLE_MOTION(0x00181134),
    TABLE_VERTICAL_INCREMENT(0x00181135),
    TABLE_LATERAL_INCREMENT(0x00181136),
    TABLE_LONGITUDINAL_INCREMENT(0x00181137),
    TABLE_ANGLE(0x00181138),
    TABLE_TYPE(0x0018113a),
    ROTATION_DIRECTION(0x00181140),
    ANGULAR_POSITION(0x00181141),
    RADIAL_POSITION(0x00181142),
    SCAN_ARC(0x00181143),
    ANGULAR_STEP(0x00181144),
    CENTER_OF_ROTATION_OFFSET(0x00181145),
    FOV_SHAPE(0x00181147),
    FOV_DIMENSIONS(0x00181149),
    EXPOSURE_TIME(0x00181150),
    XRAY_TUBE_CURRENT(0x00181151),
    EXPOSURE(0x00181152),
    EXPOSURE_IN_UAS(0x00181153),
    AVERAGE_PULSE_WIDTH(0x00181154),
    RADIATION_SETTING(0x00181155),
    RECTIFICATION_TYPE(0x00181156),
    RADIATION_MODE(0x0018115a),
    IMAGE_AREA_DOSE_PRODUCT(0x0018115e),
    FILTER_TYPE(0x00181160),
    TYPE_OF_FILTERS(0x00181161),
    INTENSIFIER_SIZE(0x00181162),
    IMAGER_PIXEL_SPACING(0x00181164),
    GRID(0x00181166),
    GENERATOR_POWER(0x00181170),
    COLLIMATOR_GRID_NAME(0x00181180),
    COLLIMATOR_TYPE(0x00181181),
    FOCAL_DISTANCE(0x00181182),
    X_FOCUS_CENTER(0x00181183),
    Y_FOCUS_CENTER(0x00181184),
    FOCAL_SPOTS(0x00181190),
    ANODE_TARGET_MATERIAL(0x00181191),
    BODY_PART_THICKNESS(0x001811a0),
    COMPRESSION_FORCE(0x001811a2),
    DATE_OF_LAST_CALIBRATION(0x00181200),
    TIME_OF_LAST_CALIBRATION(0x00181201),
    CONVOLUTION_KERNEL(0x00181210),
    ACTUAL_FRAME_DURATION(0x00181242),
    COUNT_RATE(0x00181243),
    PREFERRED_PLAYBACK_SEQUENCING(0x00181244),
    RECEIVE_COIL_NAME(0x00181250),
    TRANSMIT_COIL_NAME(0x00181251),
    PLATE_TYPE(0x00181260),
    PHOSPHOR_TYPE(0x00181261),
    SCAN_VELOCITY(0x00181300),
    WHOLE_BODY_TECHNIQUE(0x00181301),
    SCAN_LENGTH(0x00181302),
    ACQUISITION_MATRIX(0x00181310),
    INPLANE_PHASE_ENCODING_DIRECTION(0x00181312),
    FLIP_ANGLE(0x00181314),
    VARIABLE_FLIP_ANGLE_FLAG(0x00181315),
    SAR(0x00181316),
    DB_DT(0x00181318),
    ACQUISITION_DEVICE_PROCESSING_DESCRIPTION(0x00181400),
    ACQUISITION_DEVICE_PROCESSING_CODE(0x00181401),
    CASSETTE_ORIENTATION(0x00181402),
    CASSETTE_SIZE(0x00181403),
    EXPOSURES_ON_PLATE(0x00181404),
    RELATIVE_XRAY_EXPOSURE(0x00181405),
    COLUMN_ANGULATION(0x00181450),
    TOMO_LAYER_HEIGHT(0x00181460),
    TOMO_ANGLE(0x00181470),
    TOMO_TIME(0x00181480),
    TOMO_TYPE(0x00181490),
    TOMO_CLASS(0x00181491),
    NUMBER_OF_TOMOSYNTHESIS_SOURCE_IMAGES(0x00181495),
    POSITIONER_MOTION(0x00181500),
    POSITIONER_TYPE(0x00181508),
    POSITIONER_PRIMARY_ANGLE(0x00181510),
    POSITIONER_SECONDARY_ANGLE(0x00181511),
    POSITIONER_PRIMARY_ANGLE_INCREMENT(0x00181520),
    POSITIONER_SECONDARY_ANGLE_INCREMENT(0x00181521),
    DETECTOR_PRIMARY_ANGLE(0x00181530),
    DETECTOR_SECONDARY_ANGLE(0x00181531),
    SHUTTER_SHAPE(0x00181600),
    SHUTTER_LEFT_VERTICAL_EDGE(0x00181602),
    SHUTTER_RIGHT_VERTICAL_EDGE(0x00181604),
    SHUTTER_UPPER_HORIZONTAL_EDGE(0x00181606),
    SHUTTER_LOWER_HORIZONTAL_EDGE(0x00181608),
    CENTER_OF_CIRCULAR_SHUTTER(0x00181610),
    RADIUS_OF_CIRCULAR_SHUTTER(0x00181612),
    VERTICES_OF_POLYGONAL_SHUTTER(0x00181620),
    SHUTTER_PRESENTATION_VALUE(0x00181622),
    SHUTTER_OVERLAY_GROUP(0x00181623),
    COLLIMATOR_SHAPE(0x00181700),
    COLLIMATOR_LEFT_VERTICAL_EDGE(0x00181702),
    COLLIMATOR_RIGHT_VERTICAL_EDGE(0x00181704),
    COLLIMATOR_UPPER_HORIZONTAL_EDGE(0x00181706),
    COLLIMATOR_LOWER_HORIZONTAL_EDGE(0x00181708),
    CENTER_OF_CIRCULAR_COLLIMATOR(0x00181710),
    RADIUS_OF_CIRCULAR_COLLIMATOR(0x00181712),
    VERTICES_OF_POLYGONAL_COLLIMATOR(0x00181720),
    ACQUISITION_TIME_SYNCHRONIZED(0x00181800),
    TIME_SOURCE(0x00181801),
    TIME_DISTRIBUTION_PROTOCOL(0x00181802),
    NTP_SOURCE_ADDRESS(0x00181803),
    PAGE_NUMBER_VECTOR(0x00182001),
    FRAME_LABEL_VECTOR(0x00182002),
    FRAME_PRIMARY_ANGLE_VECTOR(0x00182003),
    FRAME_SECONDARY_ANGLE_VECTOR(0x00182004),
    SLICE_LOCATION_VECTOR(0x00182005),
    DISPLAY_WINDOW_LABEL_VECTOR(0x00182006),
    NOMINAL_SCANNED_PIXEL_SPACING(0x00182010),
    DIGITIZING_DEVICE_TRANSPORT_DIRECTION(0x00182020),
    ROTATION_OF_SCANNED_FILM(0x00182030),
    IVUS_ACQUISITION(0x00183100),
    IVUS_PULLBACK_RATE(0x00183101),
    IVUS_GATED_RATE(0x00183102),
    IVUS_PULLBACK_START_FRAME_NUMBER(0x00183103),
    IVUS_PULLBACK_STOP_FRAME_NUMBER(0x00183104),
    LESION_NUMBER(0x00183105),
    OUTPUT_POWER(0x00185000),
    TRANSDUCER_DATA(0x00185010),
    FOCUS_DEPTH(0x00185012),
    PROCESSING_FUNCTION(0x00185020),
    POSTPROCESSING_FUNCTION(0x00185021),
    MECHANICAL_INDEX(0x00185022),
    BONE_THERMAL_INDEX(0x00185024),
    CRANIAL_THERMAL_INDEX(0x00185026),
    SOFT_TISSUE_THERMAL_INDEX(0x00185027),
    SOFT_TISSUE_FOCUS_THERMAL_INDEX(0x00185028),
    SOFT_TISSUE_SURFACE_THERMAL_INDEX(0x00185029),
    DEPTH_OF_SCAN_FIELD(0x00185050),
    PATIENT_POSITION(0x00185100),
    VIEW_POSITION(0x00185101),
    PROJECTION_EPONYMOUS_NAME_CODE(0x00185104),
    SENSITIVITY(0x00186000),
    SEQUENCE_OF_ULTRASOUND_REGIONS(0x00186011),
    REGION_SPATIAL_FORMAT(0x00186012),
    REGION_DATA_TYPE(0x00186014),
    REGION_FLAGS(0x00186016),
    REGION_LOCATION_MIN_X0(0x00186018),
    REGION_LOCATION_MIN_Y0(0x0018601a),
    REGION_LOCATION_MAX_X1(0x0018601c),
    REGION_LOCATION_MAX_Y1(0x0018601e),
    REFERENCE_PIXEL_X0(0x00186020),
    REFERENCE_PIXEL_Y0(0x00186022),
    PHYSICAL_UNITS_X_DIRECTION(0x00186024),
    PHYSICAL_UNITS_Y_DIRECTION(0x00186026),
    REFERENCE_PIXEL_PHYSICAL_VALUE_X(0x00186028),
    REFERENCE_PIXEL_PHYSICAL_VALUE_Y(0x0018602a),
    PHYSICAL_DELTA_X(0x0018602c),
    PHYSICAL_DELTA_Y(0x0018602e),
    TRANSDUCER_FREQUENCY(0x00186030),
    TRANSDUCER_TYPE(0x00186031),
    PULSE_REPETITION_FREQUENCY(0x00186032),
    DOPPLER_CORRECTION_ANGLE(0x00186034),
    STEERING_ANGLE(0x00186036),
    DOPPLER_SAMPLE_VOLUME_X_POSITION(0x00186039),
    DOPPLER_SAMPLE_VOLUME_Y_POSITION(0x0018603b),
    TM_LINE_POSITION_X0(0x0018603d),
    TM_LINE_POSITION_Y0(0x0018603f),
    TM_LINE_POSITION_X1(0x00186041),
    TM_LINE_POSITION_Y1(0x00186043),
    PIXEL_COMPONENT_ORGANIZATION(0x00186044),
    PIXEL_COMPONENT_MASK(0x00186046),
    PIXEL_COMPONENT_RANGE_START(0x00186048),
    PIXEL_COMPONENT_RANGE_STOP(0x0018604a),
    PIXEL_COMPONENT_PHYSICAL_UNITS(0x0018604c),
    PIXEL_COMPONENT_DATA_TYPE(0x0018604e),
    NUMBER_OF_TABLE_BREAK_POINTS(0x00186050),
    TABLE_OF_X_BREAK_POINTS(0x00186052),
    TABLE_OF_Y_BREAK_POINTS(0x00186054),
    NUMBER_OF_TABLE_ENTRIES(0x00186056),
    TABLE_OF_PIXEL_VALUES(0x00186058),
    TABLE_OF_PARAMETER_VALUES(0x0018605a),
    R_WAVE_TIME_VECTOR(0x00186060),
    DETECTOR_CONDITIONS_NOMINAL_FLAG(0x00187000),
    DETECTOR_TEMPERATURE(0x00187001),
    DETECTOR_TYPE(0x00187004),
    DETECTOR_CONFIGURATION(0x00187005),
    DETECTOR_DESCRIPTION(0x00187006),
    DETECTOR_MODE(0x00187008),
    DETECTOR_ID(0x0018700a),
    DATE_OF_LAST_DETECTOR_CALIBRATION(0x0018700c),
    TIME_OF_LAST_DETECTOR_CALIBRATION(0x0018700e),
    DETECTOR_TIME_SINCE_LAST_EXPOSURE(0x00187012),
    DETECTOR_ACTIVE_TIME(0x00187014),
    DETECTOR_ACTIVATION_OFFSET(0x00187016),
    DETECTOR_BINNING(0x0018701a),
    DETECTOR_ELEMENT_PHYSICAL_SIZE(0x00187020),
    DETECTOR_ELEMENT_SPACING(0x00187022),
    DETECTOR_ACTIVE_SHAPE(0x00187024),
    DETECTOR_ACTIVE_DIMENSIONS(0x00187026),
    DETECTOR_ACTIVE_ORIGIN(0x00187028),
    DETECTOR_MANUFACTURER_NAME(0x0018702a),
    DETECTOR_MODEL_NAME(0x0018702b),
    FOV_ORIGIN(0x00187030),
    FOV_ROTATION(0x00187032),
    FOV_HORIZONTAL_FLIP(0x00187034),
    GRID_ABSORBING_MATERIAL(0x00187040),
    GRID_SPACING_MATERIAL(0x00187041),
    GRID_THICKNESS(0x00187042),
    GRID_PITCH(0x00187044),
    GRID_ASPECT_RATIO(0x00187046),
    GRID_PERIOD(0x00187048),
    GRID_FOCAL_DISTANCE(0x0018704c),
    FILTER_MATERIAL(0x00187050),
    FILTER_THICKNESS_MIN(0x00187052),
    FILTER_THICKNESS_MAX(0x00187054),
    EXPOSURE_CONTROL_MODE(0x00187060),
    STUDY_INSTANCE_UID(0x0020000d),
    SERIES_INSTANCE_UID(0x0020000e),
    STUDY_ID(0x00200010),
    SERIES_NUMBER(0x00200011),
    ACQUISITION_NUMBER(0x00200012),
    INSTANCE_NUMBER(0x00200013),
    PATIENT_ORIENTATION(0x00200020),
    IMAGE_POSITION(0x00200030),
    IMAGE_POSITION_PATIENT(0x00200032),
    IMAGE_ORIENTATION_PATIENT(0x00200037),
    LOCATION(0x00200050),
    FRAME_OF_REFERENCE_UID(0x00200052),
    IMAGE_GEOMETRY_TYPE(0x00200070),
    ACQUISITIONS_IN_SERIES(0x00201001),
    REFERENCE(0x00201020),
    SLICE_LOCATION(0x00201041),
    SAMPLES_PER_PIXEL(0x00280002),
    SAMPLES_PER_PIXEL_USED(0x00280003),
    PHOTOMETRIC_INTERPRETATION(0x00280004),
    PLANAR_CONFIGURATION(0x00280006),
    NUMBER_OF_FRAMES(0x00280008),
    FRAME_INCREMENT_POINTER(0x00280009),
    FRAME_DIMENSION_POINTER(0x0028000a),
    ROWS(0x00280010),
    COLUMNS(0x00280011),
    PLANES(0x00280012),
    ULTRASOUND_COLOR_DATA_PRESENT(0x00280014),
    PIXEL_SPACING(0x00280030),
    ZOOM_FACTOR(0x00280031),
    ZOOM_CENTER(0x00280032),
    PIXEL_ASPECT_RATIO(0x00280034),
    CORRECTED_IMAGE(0x00280051),
    BITS_ALLOCATED(0x00280100),
    BITS_STORED(0x00280101),
    HIGH_BIT(0x00280102),
    PIXEL_REPRESENTATION(0x00280103),
    SMALLEST_IMAGE_PIXEL_VALUE(0x00280106),
    LARGEST_IMAGE_PIXEL_VALUE(0x00280107),
    SMALLEST_PIXEL_VALUE_IN_SERIES(0x00280108),
    LARGEST_PIXEL_VALUE_IN_SERIES(0x00280109),
    SMALLEST_IMAGE_PIXEL_VALUE_IN_PLANE(0x00280110),
    LARGEST_IMAGE_PIXEL_VALUE_IN_PLANE(0x00280111),
    PIXEL_PADDING_VALUE(0x00280120),
    QUALITY_CONTROL_IMAGE(0x00280300),
    BURNED_IN_ANNOTATION(0x00280301),
    PIXEL_INTENSITY_RELATIONSHIP(0x00281040),
    PIXEL_SIGN(0x00281041),
    WINDOW_CENTER(0x00281050),
    WINDOW_WIDTH(0x00281051),
    RESCALE_INTERCEPT(0x00281052),
    RESCALE_SLOPE(0x00281053),
    RESCALE_TYPE(0x00281054),
    WINDOW_CENTER_AND_WIDTH_EXPLANATION(0x00281055),
    RECOMMENDED_VIEWING_MODE(0x00281090),
    RED_LUT_DESCRIPTOR(0x00281101),
    GREEN_LUT_DESCRIPTOR(0x00281102),
    BLUE_LUT_DESCRIPTOR(0x00281103),
    PALETTE_LUT_UID(0x00281199),
    RED_LUT_DATA(0x00281201),
    GREEN_LUT_DATA(0x00281202),
    BLUE_LUT_DATA(0x00281203),
    SEGMENTED_RED_LUT_DATA(0x00281221),
    SEGMENTED_GREEN_LUT_DATA(0x00281222),
    SEGMENTED_BLUE_LUT_DATA(0x00281223),
    IMPLANT_PRESENT(0x00281300),
    PARTIAL_VIEW(0x00281350),
    PARTIAL_VIEW_DESCRIPTION(0x00281351),
    LOSSY_IMAGE_COMPRESSION(0x00282110),
    LOSSY_IMAGE_COMPRESSION_RATIO(0x00282112),
    LOSSY_IMAGE_COMPRESSION_METHOD(0x00282114),
    MODALITY_LUT_SEQUENCE(0x00283000),
    LUT_DESCRIPTOR(0x00283002),
    LUT_EXPLANATION(0x00283003),
    MODALITY_LUT_TYPE(0x00283004),
    LUT_DATA(0x00283006),
    VOI_LUT_SEQUENCE(0x00283010),
    SOFTCOPY_VOI_LUT_SEQUENCE(0x00283110),
    BIPLANE_ACQUISITION_SEQUENCE(0x00285000),
    REPRESENTATIVE_FRAME_NUMBER(0x00286010),
    FRAME_NUMBERS_OF_INTEREST(0x00286020),
    FRAME_OF_INTEREST_DESCRIPTION(0x00286022),
    FRAME_OF_INTEREST_TYPE(0x00286023),
    R_WAVE_POINTER(0x00286040),
    MASK_SUBTRACTION_SEQUENCE(0x00286100),
    MASK_OPERATION(0x00286101),
    APPLICABLE_FRAME_RANGE(0x00286102),
    MASK_FRAME_NUMBERS(0x00286110),
    CONTRAST_FRAME_AVERAGING(0x00286112),
    MASK_SUBPIXEL_SHIFT(0x00286114),
    TID_OFFSET(0x00286120),
    MASK_OPERATION_EXPLANATION(0x00286190),
    DATA_POINT_ROWS(0x00289001),
    DATA_POINT_COLUMNS(0x00289002),
    SIGNAL_DOMAIN_COLUMNS(0x00289003),
    DATA_REPRESENTATION(0x00289108),
    PIXEL_MEASURES_SEQUENCE(0x00289110),
    FRAME_VOI_LUT_SEQUENCE(0x00289132),
    PIXEL_VALUE_TRANSFORMATION_SEQUENCE(0x00289145),
    SIGNAL_DOMAIN_ROWS(0x00289235),
    NUMBER_OF_ENERGY_WINDOWS(0x00540011),
    NUMBER_OF_DETECTORS(0x00540021),
    NUMBER_OF_ROTATIONS(0x00540051),
    SLICE_VECTOR(0x00540080),
    NUMBER_OF_SLICES(0x00540081),
    TYPE_OF_DETECTOR_MOTION(0x00540202),
    IMAGE_ID(0x00540400),
    ICON_IMAGE_SEQUENCE(0x00880200),
    BORDER_DENSITY(0x20100100),

    PIXEL_DATA_LENGTH(0x7FE00000),
    EXTENDED_OFFSET_TABLE(0x7FE00001),
    EXTENDED_OFFSET_TABLE_LENGTHS(0x7FE00002),
    FLOAT_PIXEL_DATA(0x7FE00008),
    DOUBLE_FLOAT_PIXEL_DATA(0x7FE00009),
    PIXEL_DATA(0x7FE00010),
    ITEM(0xFFFEE000),
    ITEM_DELIMITATION_ITEM(0xFFFEE00D),
    SEQUENCE_DELIMITATION_ITEM(0xFFFEE0DD),
    TRAILING_PADDING(0xFFFCFFFC),

    // directory structuring elements
    FILE_SET_ID(0x00041130),
    FILE_SET_DESCRIPTOR_FILE_ID(0x00041141),
    CHARSET_OF_FILE_SET_DESCRIPTOR_FILE(0x00041142),
    OFFSET_FIRST_DIRECTORY_RECORD(0x00041200),
    OFFSET_LAST_DIRECTORY_RECORD(0x00041202),
    FILE_SET_CONSISTENCY_FLAG(0x00041212),
    DIRECTORY_RECORD_SEQUENCE(0x00041220),
    OFFSET_OF_NEXT_DIRECTORY_RECORD(0x00041400),
    RECORD_IN_USE_FLAG(0x00041410),
    OFFSET_OF_REFERENCED_DIRECTORY(0x00041420),
    DIRECTORY_RECORD_TYPE(0x00041430),
    PRIVATE_RECORD_UID(0x00041432),
    REFERENCED_FILE_ID(0x00041500),
    MRDR_RECORD_OFFSET(0x00041504),
    REFERENCED_SOP_CLASS_UID_FILE(0x00041510),
    REFERENCED_SOP_INSTANCE_UID_FILE(0x00041511),
    REFERENCED_TRANSFER_SYNTAX_UID_FILE(0x00041512),
    REFERENCED_RELATED_SOP_CLASS_UID_FILE(0x0004151A),
    NUMBER_OF_REFERENCES(0x00041600),

    // remaining whole slide microscopy image module and related attributes
    ACQUISITION_DURATION(0x00189073),
    DIMENSION_ORGANIZATION_TYPE(0x00209311),
    DIMENSION_INDEX_SEQUENCE(0x00209222),
    DIMENSION_INDEX_POINTER(0x00209165),
    DIMENSION_INDEX_PRIVATE_CREATOR(0x00209213),
    FUNCTIONAL_GROUP_POINTER(0x00209167),
    FUNCTIONAL_GROUP_PRIVATE_CREATOR(0x00209238),
    IN_CONCATENATION_NUMBER(0x00209162),
    CONCATENATION_FRAME_OFFSET_NUMBER(0x00209228),
    DIMENSION_ORGANIZATION_UID(0x00209164),
    DIMENSION_ORGANIZATION_SEQUENCE(0x00209221),
    DIMENSION_DESCRIPTION_LABEL(0x00209421),
    ILLUMINATION_WAVELENGTH(0x00220055),
    ILLUMINATION_TYPE_CODE_SEQUENCE(0x00220016),
    LIGHT_PATH_FILTER_TYPE_STACK_CODE_SEQUENCE(0x00220017),
    LIGHT_PATH_FILTER_PASSTHROUGH_WAVELENGTH(0x00220001),
    LIGHT_PATH_FILTER_PASS_BAND(0x00220002),
    IMAGE_PATH_FILTER_PASSTHROUGH_WAVELENGTH(0x00220003),
    IMAGE_PATH_FILTER_PASS_BAND(0x00220004),
    IMAGE_PATH_FILTER_TYPE_STACK_CODE_SEQUENCE(0x00220018),
    LENSES_CODE_SEQUENCE(0x00220019),
    CHANNEL_DESCRIPTION_CODE_SEQUENCE(0x0022001A),
    ICC_PROFILE(0x00282000),
    COLOR_SPACE(0x00282002),
    CONTAINER_ID(0x00400512),
    CONTAINER_ID_ISSUER_SEQUENCE(0x00400513),
    CONTAINER_TYPE_CODE_SEQUENCE(0x00400518),
    SPECIMEN_ID(0x00400551),
    SPECIMEN_UID(0x00400554),
    ACQUISITION_CONTEXT_SEQUENCE(0x00400555),
    SPECIMEN_DESCRIPTION_SEQUENCE(0x00400560),
    SPECIMEN_ID_ISSUER_SEQUENCE(0x00400562),
    SPECIMEN_PREP_SEQUENCE(0x00400610),
    WHOLE_SLIDE_FRAME_TYPE_SEQUENCE(0x00400710),
    X_OFFSET_IN_SLIDE(0x0040072a),
    Y_OFFSET_IN_SLIDE(0x0040073a),
    Z_OFFSET_IN_SLIDE(0x0040074a),
    IMAGED_VOLUME_WIDTH(0x00480001),
    IMAGED_VOLUME_HEIGHT(0x00480002),
    IMAGED_VOLUME_DEPTH(0x00480003),
    TOTAL_PIXEL_MATRIX_COLUMNS(0x00480006),
    TOTAL_PIXEL_MATRIX_ROWS(0x00480007),
    TOTAL_PIXEL_MATRIX_ORIGIN_SEQUENCE(0x00480008),
    SPECIMEN_LABEL_IN_IMAGE(0x00480010),
    FOCUS_METHOD(0x00480011),
    EXTENDED_DEPTH_OF_FIELD(0x00480012),
    NUMBER_OF_FOCAL_PLANES(0x00480013),
    DISTANCE_BETWEEN_FOCAL_PLANES(0x00480014),
    RECOMMENDED_ABSENT_PIXEL_CIELAB_VALUE(0x00480015),
    SLIDE_IMAGE_ORIENTATION(0x00480102),
    OPTICAL_PATH_SEQUENCE(0x00480105),
    OPTICAL_PATH_ID(0x00480106),
    OPTICAL_PATH_DESCRIPTION(0x00480107),
    ILLUMINATOR_TYPE_CODE_SEQUENCE(0x00480100),
    ILLUMINATION_COLOR_CODE_SEQUENCE(0x00480108),
    CONDENSER_LENS_POWER(0x00480111),
    OBJECTIVE_LENS_POWER(0x00480112),
    OBJECTIVE_LENS_NA(0x00480113),
    PALETTE_COLOR_LUT_SEQUENCE(0x00480120),
    REFERENCED_IMAGE_NAVIGATION_SEQUENCE(0x00480200),
    OPTICAL_PATH_ID_SEQUENCE(0x00480207),
    NUMBER_OPTICAL_PATHS(0x00480302),
    TOTAL_PIXEL_MATRIX_FOCAL_PLANES(0x00480303),
    PRESENTATION_LUT_SHAPE(0x20500020),

    PLANE_POSITION_SLIDE_SEQUENCE(0x0048021A),
    COLUMN_POSITION_IN_MATRIX(0x0048021E),
    ROW_POSITION_IN_MATRIX(0x0048021F),

    FRAME_CONTENT_SEQUENCE(0x00209111),
    FRAME_ACQUISITION_DATETIME(0x00189074),
    FRAME_REFERENCE_DATETIME(0x00189151),
    FRAME_ACQUISITION_DURATION(0x00189220),
    DIMENSION_INDEX_VALUES(0x00209157),
    SHARED_FUNCTIONAL_GROUPS_SEQUENCE(0x52009229),
    PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE(0x52009230),

    BARCODE_VALUE(0x22000005),
    LABEL_TEXT(0x22000002),

    VARIABLE_PIXEL_DATA(0x7f880010),
    INVALID_PIXEL_DATA(0xffee000),
    INVALID(0);

    private int tag;
    private String description;
    private DicomVR defaultVR;

    private static final Map<Integer, DicomAttribute> lookup =
      new HashMap<Integer, DicomAttribute>();

    private static final Map<Integer, String[]> dict =
      new HashMap<Integer, String[]>();
    private static final Map<String, Integer> nameLookup =
      new HashMap<String, Integer>();

		static {
      try (InputStream stream = DicomAttribute.class.getResourceAsStream("dicom-dictionary.txt")) {
        BufferedReader in = new BufferedReader(new InputStreamReader(stream, Constants.ENCODING));
        while (true) {
          String line = in.readLine();
          if (line == null) {
            break;
          }

          String[] tokens = line.split(",");
          tokens[1] = tokens[1].replaceAll("\"", "").trim();
          if (tokens.length > 2) {
            tokens[2] = tokens[2].trim();
          }
          int key = (int) Long.parseLong(tokens[0], 16);
          dict.put(key, tokens);
          nameLookup.put(tokens[1].replaceAll("\\s", "").toLowerCase(), key);
        }
      }
      catch (Exception e) {
        throw new IllegalArgumentException(e);
      }

      for (DicomAttribute v : EnumSet.allOf(DicomAttribute.class)) {
        lookup.put(v.getTag(), v);
      }
		}

    private DicomAttribute(int tag) {
      this.tag = tag;
    }

    private void update() {
      if (description == null && dict.containsKey(tag)) {
        String[] tokens = dict.get(tag);
        description = tokens[1];
        if (tokens.length > 2) {
          defaultVR = DicomVR.valueOf(tokens[2]);
        }
      }
    }

    /**
     * Get the known default VR for this attribute, or IMPLICIT if
     * our dictionary does not include a default VR.
     *
     * @return default VR or IMPLICIT, should not be null
     */
    public DicomVR getDefaultVR() {
      update();
      return defaultVR;
    }

    public static DicomVR getDefaultVR(int newTag) {
      if (dict.containsKey(newTag) && dict.get(newTag).length > 2) {
        return DicomVR.valueOf(dict.get(newTag)[2]);
      }
      return IMPLICIT;
    }

    /**
     * Get the 4 byte integer tag.
     *
     * @return tag
     */
    public int getTag() {
      return tag;
    }

    /**
     * Get the human-readable description associated with this attribute.
     *
     * @return description
     */
    public String getDescription() {
      update();
      return description;
    }

    public static String getDescription(int newTag) {
      if (dict.containsKey(newTag)) {
        return dict.get(newTag)[1];
      }
      return null;
    }

    public static Integer getTag(String description) {
      return nameLookup.get(description.toLowerCase());
    }

    /**
     * Lookup the attribute for the given tag.
     * May return null if the tag is not defined in our dictionary.
     *
     * @param newTag 4 byte DICOM tag
     * @return corresponding attribute, or null if not defined
     */
    public static DicomAttribute get(int newTag) {
      DicomAttribute v = lookup.get(newTag);
      if (v != null) {
        v.update();
      }
      return v;
    }

    /**
     * Format the given tag as a pair of comma-separated hex strings.
     * For an input integer 0x89abcdef, the return value will be
     * "89ab,cdef". This is similar to the format used in the DICOM schema.
     * The tag need not be included in our dictionary.
     *
     * @param tag 4 byte DICOM tag
     * @return corresponding hex string
     */
    public static String formatTag(int tag) {
      String s = Integer.toHexString(tag);
      while (s.length() < 8) {
        s = "0" + s;
      }
      return s.substring(0, 4) + "," + s.substring(4);
    }
}
